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.sourceforge.net/>
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)
00070 #define OB_RINGFLAGS_MOL         (1<<2)
00072 #define OB_AROMATIC_MOL          (1<<3)
00074 #define OB_ATOMTYPES_MOL         (1<<4)
00076 #define OB_CHIRALITY_MOL         (1<<5)
00078 #define OB_PCHARGE_MOL           (1<<6)
00080 #define OB_HYBRID_MOL            (1<<8)
00082 #define OB_IMPVAL_MOL            (1<<9)
00084 #define OB_KEKULE_MOL            (1<<10)
00086 #define OB_CLOSURE_MOL           (1<<11)
00088 #define OB_H_ADDED_MOL           (1<<12)
00090 #define OB_PH_CORRECTED_MOL      (1<<13)
00092 #define OB_AROM_CORRECTED_MOL    (1<<14)
00094 #define OB_CHAINS_MOL            (1<<15)
00096 #define OB_TCHARGE_MOL                 (1<<16)
00098 #define OB_TSPIN_MOL             (1<<17)
00100 #define OB_RINGTYPES_MOL         (1<<18)
00102 #define OB_PATTERN_STRUCTURE     (1<<19)
00103   // flags 19-32 unspecified
00104 #define OB_CURRENT_CONFORMER     -1
00105 
00106   // class introduction in mol.cpp
00107  class OBAPI OBMol: public OBBase
00108   {
00109   protected:
00110     int                           _flags;       
00111     bool                          _autoPartialCharge;
00112     bool                          _autoFormalCharge;
00113     std::string                   _title;       
00114     std::vector<OBAtom*>          _vatom;       
00115     std::vector<OBAtom*>          _atomIds;     
00116     std::vector<OBBond*>          _vbond;       
00117     std::vector<OBBond*>          _bondIds;     
00118     unsigned short int            _dimension;   
00119     int                           _totalCharge; 
00120     unsigned int                  _totalSpin;   
00121     double                        *_c;          
00122     std::vector<double*>          _vconf;       
00123     double                        _energy;      
00124     unsigned int                  _natoms;      
00125     unsigned int                  _nbonds;      
00126     std::vector<OBResidue*>       _residue;     
00127     std::vector<OBInternalCoord*> _internals;   
00128     unsigned short int            _mod;         
00129 
00130     bool  HasFlag(int flag)    { return((_flags & flag) ? true : false); }
00131     void  SetFlag(int flag)    { _flags |= flag; }
00132 
00134 
00135     void start_kekulize(std::vector <OBAtom*> &cycle, std::vector<int> &electron);
00136     bool expand_kekulize(int bond_idx, std::vector<int> &atomState, std::vector<int> &bondState);
00137     bool has_no_leftover_electrons(std::vector<int> &atomState);
00138     int getorden(OBAtom *atom);
00139     bool expandcycle(OBAtom *atom, OBBitVec &avisit, OBAtom *first = NULL, int depth = 0);
00141 
00142   public:
00143 
00145 
00146 
00147     OBMol();
00149     OBMol(const OBMol &);
00151     virtual ~OBMol();
00153     OBMol &operator=(const OBMol &mol);      
00155     OBMol &operator+=(const OBMol &mol);
00156 
00159     void ReserveAtoms(int natoms)
00160     {
00161       if (natoms > 0 && _mod) {
00162         _vatom.reserve(natoms);
00163         _atomIds.reserve(natoms);
00164       }
00165     }
00166     
00169     virtual OBAtom *CreateAtom(void);
00172     virtual OBBond *CreateBond(void);
00175     virtual OBResidue *CreateResidue(void);
00178     virtual void DestroyAtom(OBAtom*);
00181     virtual void DestroyBond(OBBond*);
00184     virtual void DestroyResidue(OBResidue*);
00185 
00188     bool AddAtom(OBAtom&);
00191     bool InsertAtom(OBAtom &);
00199     bool AddBond(int beginIdx, int endIdx, int order, 
00200                  int flags=0,int insertpos=-1);
00203     bool AddBond(OBBond&);
00206     bool AddResidue(OBResidue&);
00207 
00211     OBAtom    *NewAtom();
00215     OBAtom    *NewAtom(unsigned long id);
00219     OBBond    *NewBond();
00223     OBBond    *NewBond(unsigned long id);
00225     OBResidue *NewResidue();
00230     bool DeleteAtom(OBAtom*, bool destroyAtom = true);
00233     bool DeleteBond(OBBond*, bool destroyBond = true);
00236     bool DeleteResidue(OBResidue*, bool destroyResidue = true);
00238 
00240 
00241 
00242 
00243 
00244     virtual void BeginModify(void);
00248     virtual void EndModify(bool nukePerceivedData=true);
00250     int GetMod()           {      return(_mod);    }
00253     void IncrementMod()    {      _mod++;          }
00256     void DecrementMod()    {      _mod--;          }
00258 
00260 
00261 
00262     int          GetFlags()               { return(_flags); }
00265     const char  *GetTitle(bool replaceNewlines = true) const;
00267     unsigned int NumAtoms() const         {  return(_natoms); }
00269     unsigned int NumBonds() const         {  return(_nbonds); }
00271     unsigned int NumHvyAtoms();
00273     unsigned int NumResidues() const      { return(static_cast<unsigned int> (_residue.size())); }
00275     unsigned int NumRotors();
00276     
00279     OBAtom      *GetAtom(int idx) const;
00281     OBAtom      *GetAtomById(unsigned long id) const;
00284     OBAtom      *GetFirstAtom() const;
00287     OBBond      *GetBond(int idx) const;
00289     OBBond      *GetBondById(unsigned long id) const;
00292     OBBond      *GetBond(int a, int b) const;
00293     // The safer version of the above method
00295     OBBond      *GetBond(OBAtom* bgn, OBAtom* end) const;
00298     OBResidue   *GetResidue(int idx) const;
00299     std::vector<OBInternalCoord*> GetInternalCoord();
00304     double       GetTorsion(int,int,int,int);
00309     double       GetTorsion(OBAtom* a,OBAtom* b,OBAtom* c,OBAtom* d);
00312     double GetAngle(OBAtom* a, OBAtom* b, OBAtom* c);
00314     std::string  GetFormula();
00316     std::string  GetSpacedFormula(int ones=0, const char* sp=" ", bool implicitH = true);
00318     double       GetEnergy() const { return _energy; }
00320     double       GetMolWt(bool implicitH = true);
00322     double       GetExactMass(bool implicitH = true);
00324     int          GetTotalCharge();
00326     unsigned int GetTotalSpinMultiplicity();
00328     unsigned short int GetDimension() const { return _dimension; }
00330     double      *GetCoordinates() { return(_c); }
00332     std::vector<OBRing*> &GetSSSR();
00334     bool AutomaticFormalCharge()   { return(_autoFormalCharge);  }
00336     bool AutomaticPartialCharge()  { return(_autoPartialCharge); }
00338 
00339 
00341 
00342 
00343     void   SetTitle(const char *title);
00345     void   SetTitle(std::string &title);
00347     void   SetFormula(std::string molFormula);
00349     void   SetEnergy(double energy) { _energy = energy; }
00351     void   SetDimension(unsigned short int d) { _dimension = d; }
00353     void   SetTotalCharge(int charge);
00356     void   SetTotalSpinMultiplicity(unsigned int spinMultiplicity);
00359     void   SetInternalCoord(std::vector<OBInternalCoord*> int_coord)
00360     { _internals = int_coord; }
00362     void SetAutomaticFormalCharge(bool val)
00363     { _autoFormalCharge=val;  }
00365     void SetAutomaticPartialCharge(bool val)
00366     { _autoPartialCharge=val; }
00367 
00369     void   SetAromaticPerceived()    { SetFlag(OB_AROMATIC_MOL);    }
00371     void   SetSSSRPerceived()        { SetFlag(OB_SSSR_MOL);        }
00373     void   SetRingAtomsAndBondsPerceived(){SetFlag(OB_RINGFLAGS_MOL);}
00375     void   SetAtomTypesPerceived()   { SetFlag(OB_ATOMTYPES_MOL);   }
00377     void   SetRingTypesPerceived()   { SetFlag(OB_RINGTYPES_MOL);   }
00379     void   SetChainsPerceived()      { SetFlag(OB_CHAINS_MOL);      }
00381     void   SetChiralityPerceived()   { SetFlag(OB_CHIRALITY_MOL);   }
00383     void   SetPartialChargesPerceived(){ SetFlag(OB_PCHARGE_MOL);   }
00385     void   SetHybridizationPerceived() { SetFlag(OB_HYBRID_MOL);    }
00387     void   SetImplicitValencePerceived(){ SetFlag(OB_IMPVAL_MOL);   }
00389     void   SetKekulePerceived()      { SetFlag(OB_KEKULE_MOL);      }
00391     void   SetClosureBondsPerceived(){ SetFlag(OB_CLOSURE_MOL);     }
00393     void   SetHydrogensAdded()       { SetFlag(OB_H_ADDED_MOL);     }
00394     void   SetCorrectedForPH()       { SetFlag(OB_PH_CORRECTED_MOL);}
00395     void   SetAromaticCorrected()    { SetFlag(OB_AROM_CORRECTED_MOL);}
00396     void   SetSpinMultiplicityAssigned(){ SetFlag(OB_TSPIN_MOL);    }
00397     void   SetFlags(int flags)       { _flags = flags;              }
00398 
00399     void   UnsetAromaticPerceived()  { _flags &= (~(OB_AROMATIC_MOL));   }
00400     void   UnsetSSSRPerceived()  { _flags &= (~(OB_SSSR_MOL));   }
00401     void   UnsetRingTypesPerceived()  { _flags &= (~(OB_RINGTYPES_MOL));   }
00402     void   UnsetPartialChargesPerceived(){ _flags &= (~(OB_PCHARGE_MOL));}
00403     void   UnsetImplicitValencePerceived(){_flags &= (~(OB_IMPVAL_MOL)); }
00404     void   UnsetHydrogensAdded()       { UnsetFlag(OB_H_ADDED_MOL);     }
00405     void   UnsetFlag(int flag)       { _flags &= (~(flag));              }
00407 
00409 
00410     // Description in transform.cpp (command-line transformations to this molecule)
00411     virtual OBBase*    DoTransformations(const std::map<std::string,std::string>* pOptions,OBConversion* pConv);
00412     // Ditto (documentation on transformation options)
00413     static const char* ClassDescription();
00415     bool Clear();
00417     void RenumberAtoms(std::vector<OBAtom*>&);
00419     void RenumberAtoms(std::vector<int>);
00422     void SetCoordinates(double *c);
00424     void ToInertialFrame(int conf, double *rmat);
00426     void ToInertialFrame();
00428     void Translate(const vector3 &v);
00430     void Translate(const vector3 &v, int conf);
00432     void Rotate(const double u[3][3]);
00434     void Rotate(const double m[9]);
00436     void Rotate(const double m[9],int nconf);
00438     void Center();
00440     
00441     bool Kekulize();
00442     bool PerceiveKekuleBonds();
00443 
00444     void NewPerceiveKekuleBonds();
00445 
00448     bool DeleteHydrogens();
00451     bool DeleteHydrogens(OBAtom*);
00454     bool DeleteNonPolarHydrogens();
00457     bool DeleteHydrogen(OBAtom*);
00464     bool AddHydrogens(bool polaronly=false,bool correctForPH=false, double pH=7.4);
00466     bool AddHydrogens(OBAtom*);
00468     bool AddPolarHydrogens();
00469 
00473     bool StripSalts(int threshold=0);
00475     std::vector<OBMol> Separate(int StartIndex=1);
00477     bool GetNextFragment( OpenBabel::OBMolAtomDFSIter& iter, OBMol& newMol );
00479     bool ConvertDativeBonds();
00480 
00482     bool CorrectForPH(double pH=7.4);
00483     // docs in mol.cpp
00484     bool AssignSpinMultiplicity(bool NoImplicitH=false);
00486     void   SetIsPatternStructure()       { SetFlag(OB_PATTERN_STRUCTURE);}
00487 
00490     vector3 Center(int nconf);
00496     void SetTorsion(OBAtom*,OBAtom*,OBAtom*,OBAtom*,double ang);
00498 
00500 
00501 
00502     void FindSSSR();
00504     void FindRingAtomsAndBonds();
00506     //void FindChiralCenters();
00507     // documented in mol.cpp -- locates all atom indexes which can reach 'end'
00508     void FindChildren(std::vector<int> & children,int bgnIdx,int endIdx);
00509     // documented in mol.cpp -- locates all atoms which can reach 'end'
00510     void FindChildren(std::vector<OBAtom*>& children,OBAtom* bgn,OBAtom* end);
00515     void FindLargestFragment(OBBitVec &frag);
00518     void ContigFragList(std::vector<std::vector<int> >&);
00520     void Align(OBAtom*,OBAtom*,vector3&,vector3&);
00522     void ConnectTheDots();
00524     void PerceiveBondOrders();
00526     void FindAngles();
00528     void FindTorsions();
00529     // documented in mol.cpp: graph-theoretical distance for each atom
00530     bool         GetGTDVector(std::vector<int> &);
00531     // documented in mol.cpp: graph-invariant index for each atom
00532     void         GetGIVector(std::vector<unsigned int> &);
00533     // documented in mol.cpp: calculate symmetry-unique identifiers
00534     void         GetGIDVector(std::vector<unsigned int> &);
00536 
00538 
00539 
00540     bool Has2D(bool Not3D=false);
00542     bool Has3D();
00544     bool HasNonZeroCoords();
00546     bool HasAromaticPerceived()     { return(HasFlag(OB_AROMATIC_MOL)); }
00548     bool HasSSSRPerceived()         { return(HasFlag(OB_SSSR_MOL));     }
00550     bool HasRingAtomsAndBondsPerceived(){return(HasFlag(OB_RINGFLAGS_MOL));}
00552     bool HasAtomTypesPerceived()    { return(HasFlag(OB_ATOMTYPES_MOL));}
00554     bool HasRingTypesPerceived()    { return(HasFlag(OB_RINGTYPES_MOL));}
00556     bool HasChiralityPerceived()    { return(HasFlag(OB_CHIRALITY_MOL));}
00558     bool HasPartialChargesPerceived() { return(HasFlag(OB_PCHARGE_MOL));}
00560     bool HasHybridizationPerceived() { return(HasFlag(OB_HYBRID_MOL));  }
00562     bool HasImplicitValencePerceived() { return(HasFlag(OB_IMPVAL_MOL));}
00564     bool HasKekulePerceived() { return(HasFlag(OB_KEKULE_MOL));         }
00566     bool HasClosureBondsPerceived() { return(HasFlag(OB_CLOSURE_MOL));  }
00568     bool HasChainsPerceived() { return(HasFlag(OB_CHAINS_MOL));         }
00570     bool HasHydrogensAdded() { return(HasFlag(OB_H_ADDED_MOL));         }
00572     bool HasAromaticCorrected() { return(HasFlag(OB_AROM_CORRECTED_MOL));}
00574     bool IsCorrectedForPH() { return(HasFlag(OB_PH_CORRECTED_MOL));     }
00576     bool HasSpinMultiplicityAssigned() { return(HasFlag(OB_TSPIN_MOL)); }
00578     bool IsChiral();
00580     bool Empty()                       { return(_natoms == 0);          }
00582 
00584 
00585 
00586     int     NumConformers()    { return((_vconf.empty())?0:static_cast<int> (_vconf.size())); }
00588     void    SetConformers(std::vector<double*> &v);
00590     void    AddConformer(double *f)    {  _vconf.push_back(f);    }
00593     void    SetConformer(int i);
00596     void    CopyConformer(double* c,int nconf);
00598     void    DeleteConformer(int nconf);
00600     double  *GetConformer(int i)       {  return(_vconf[i]);      }
00602     void    SetEnergies(std::vector<double> &energies);
00604     std::vector<double> GetEnergies();
00607     double  GetEnergy(int ci);
00610     double  *BeginConformer(std::vector<double*>::iterator&i)
00611     { i = _vconf.begin();
00612       return((i == _vconf.end()) ? NULL:*i); }
00615     double  *NextConformer(std::vector<double*>::iterator&i)
00616     { ++i;
00617       return((i == _vconf.end()) ? NULL:*i); }
00619     std::vector<double*> &GetConformers() {   return(_vconf);     }
00621 
00623 
00624 
00625     OBAtomIterator BeginAtoms()   { return _vatom.begin(); }
00627      OBAtomIterator EndAtoms()    { return _vatom.begin() + NumAtoms() ; }
00629     OBBondIterator BeginBonds()   { return _vbond.begin(); }
00631     OBBondIterator EndBonds()     { return _vbond.begin() + NumBonds() ; }
00633     OBResidueIterator BeginResidues() { return _residue.begin(); }
00635     OBResidueIterator EndResidues()   { return _residue.end();   }
00636 
00639     OBAtom *BeginAtom(OBAtomIterator &i);
00642     OBAtom *NextAtom(OBAtomIterator &i);
00645     OBBond *BeginBond(OBBondIterator &i);
00648     OBBond *NextBond(OBBondIterator &i);
00651     OBResidue *BeginResidue(OBResidueIterator &i)
00652     {
00653       i = _residue.begin();
00654       return((i == _residue.end()) ? NULL:*i);
00655     }
00658     OBResidue *NextResidue(OBResidueIterator &i)
00659     {
00660       ++i;
00661       return((i == _residue.end()) ? NULL:*i);
00662     }
00666     OBInternalCoord *BeginInternalCoord(std::vector<OBInternalCoord*>::iterator &i)
00667     {
00668       i = _internals.begin();
00669       return((i == _internals.end()) ? NULL:*i);
00670     }
00674     OBInternalCoord *NextInternalCoord(std::vector<OBInternalCoord*>::iterator &i)
00675     {
00676       ++i;
00677       return((i == _internals.end()) ? NULL:*i);
00678     }
00680 
00681   };
00682 
00683   // Utility function prototypes
00684   //tokenize and Trim declarations moved to base.h
00685   // Deprecated -- use OBMessageHandler class instead (docs in obutil.cpp)
00686   OBAPI void ThrowError(char *str);
00687   // Deprecated -- use OBMessageHandler class instead (docs in obutil.cpp)
00688   OBAPI void ThrowError(std::string &str);
00690   OBAPI void CartesianToInternal(std::vector<OBInternalCoord*>&,OBMol&);
00692   OBAPI void InternalToCartesian(std::vector<OBInternalCoord*>&,OBMol&);
00693   // Replace the last extension in str with a new one (docs in obutil.cpp)
00694   OBAPI std::string NewExtension(std::string&,char*);
00695 
00696   //global definitions
00698   EXTERN  OBElementTable   etab;
00701   EXTERN  OBTypeTable      ttab;
00703   EXTERN  OBIsotopeTable   isotab;
00705   EXTERN  OBAromaticTyper  aromtyper;
00708   EXTERN  OBAtomTyper      atomtyper;
00710   EXTERN  OBChainsParser   chainsparser;
00712   OBERROR extern  OBMessageHandler obErrorLog;
00714   EXTERN  OBResidueData    resdat;
00715 
00716   //Utility Macros
00717 
00718 #ifndef BUFF_SIZE
00719 #define BUFF_SIZE 32768
00720 #endif
00721 
00722 #ifndef EQ
00723 #define EQ(a,b) (!strcmp((a), (b)))
00724 #endif
00725 
00726 #ifndef EQn
00727 #define EQn(a,b,n) (!strncmp((a), (b), (n)))
00728 #endif
00729 
00730 #ifndef SQUARE
00731 #define SQUARE(x) ((x)*(x))
00732 #endif
00733 
00734 #ifndef IsUnsatType
00735 #define IsUnsatType(x)  (EQ(x,"Car") || EQ(x,"C2") || EQ(x,"Sox") || EQ(x,"Sac") || EQ(x,"Pac") || EQ(x,"So2"))
00736 #endif
00737 
00738 #ifndef __KCC
00739   extern "C"
00740   {
00741     OBAPI void  get_rmat(double*,double*,double*,int);
00742     OBAPI void  ob_make_rmat(double mat[3][3],double rmat[9]);
00743     OBAPI void  qtrfit (double *r,double *f,int size,double u[3][3]);
00744     OBAPI double superimpose(double*,double*,int);
00745   }
00746 #else
00747   OBAPI void get_rmat(double*,double*,double*,int);
00748   OBAPI void ob_make_rmat(double mat[3][3],double rmat[9]);
00749   OBAPI void qtrfit (double *r,double *f,int size,double u[3][3]);
00750   OBAPI double superimpose(double*,double*,int);
00751 #endif // __KCC
00752 
00753 //  extern OBMol* (*CreateMolecule) (void);
00754 
00755 } // end namespace OpenBabel
00756 
00757 #endif // OB_MOL_H
00758