1 /********************************************************************** 2 bond.h - Handle OBBond class. 3 4 Copyright (C) 1998-2001 by OpenEye Scientific Software, Inc. 5 Some portions Copyright (C) 2001-2006 by Geoffrey R. Hutchison 6 Some portions Copyright (C) 2003 by Michael Banck 7 Some portions Copyright (C) 2008 by Tim Vandermeersch 8 9 This file is part of the Open Babel project. 10 For more information, see <http://openbabel.org/> 11 12 This program is free software; you can redistribute it and/or modify 13 it under the terms of the GNU General Public License as published by 14 the Free Software Foundation version 2 of the License. 15 16 This program is distributed in the hope that it will be useful, 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 GNU General Public License for more details. 20 ***********************************************************************/ 21 22 #ifndef OB_BOND_H 23 #define OB_BOND_H 24 25 #include <openbabel/babelconfig.h> 26 27 #ifndef OB_EXTERN 28 # define OB_EXTERN extern 29 #endif 30 31 #include <openbabel/base.h> 32 #include <openbabel/atom.h> 33 34 namespace OpenBabel 35 { 36 class OBAtom; 37 class OBRing; 38 39 //BOND Property Macros (flags) 40 //! An aromatic bond (regardless of bond order) 41 #define OB_AROMATIC_BOND (1<<1) 42 //! A solid black wedge in 2D representations -- i.e., "up" from the 2D plane 43 #define OB_WEDGE_BOND (1<<2) 44 //! A dashed "hash" bond in 2D representations -- i.e., "down" from the 2D plane 45 #define OB_HASH_BOND (1<<3) 46 //! A bond in a ring 47 #define OB_RING_BOND (1<<4) 48 //! A bond which "closes" a ring when walking the molecular graph 49 #define OB_CLOSURE_BOND (1<<10) 50 // 11-16 currently unused 51 #define OB_WEDGE_OR_HASH_BOND (1<<11) 52 53 #define SET_OR_UNSET_FLAG(X) \ 54 if (value) SetFlag(X); \ 55 else UnsetFlag(X); 56 57 58 class OBAPI OBBond: public OBBase 59 { 60 protected: 61 unsigned int _idx; //!< Unique edge index used by GetIdx() and SetIdx() 62 OBMol *_parent;//!< The molecule which contains me (if any) 63 OBAtom *_bgn; //!< I connect one node 64 OBAtom *_end; //!< to another node 65 char _order; //!< Bond order (1, 2, 3, 5=aromatic) 66 unsigned short int _flags; //!< Any flags for this bond 67 unsigned long _id; //!< unique id 68 //OBBondPrivate * const d; 69 70 /** 71 * @return True id the @p flag is set. 72 */ HasFlag(int flag)73 bool HasFlag(int flag) const { return ((_flags & flag) != 0); } 74 /** 75 * Sets the bitwise @p flag 76 */ SetFlag(int flag)77 void SetFlag(int flag) { _flags |= flag; } 78 /** 79 * Unsets the bitwise @p flag 80 */ UnsetFlag(int flag)81 void UnsetFlag(int flag) { _flags &= (~(flag)); } 82 83 public: 84 enum Flag { 85 Aromatic = (1<<1), //!< An aromatic bond (regardless of bond order) 86 Ring = (1<<4), //!< A bond in a ring 87 Closure = (1<<10) //!< A bond which "closes" a ring when walking the molecular graph 88 }; 89 enum StereoFlag { 90 Wedge = (1<<2), //!< A solid black wedge in 2D representations -- i.e., "up" from the 2D plane 91 Hash = (1<<3), //!< A dashed "hash" bond in 2D representations -- i.e., "down" from the 2D plane 92 WedgeOrHash = (1<<11), //!< The bond is either wedge or hash, this is a separate flag! 93 CisOrTrans = (1<<12) //!< Indicates the 2D/3D coordinates are accidentally cis/trans. 94 }; 95 //! Whether this bond has been visited by a graph algorithm 96 /** \deprecated Use OBBitVec objects instead to be fully thread-safe. **/ 97 bool Visit; 98 99 //! Constructor 100 OBBond(); 101 //! Destructor 102 virtual ~OBBond(); 103 104 //! \name Bond modification methods 105 //@{ 106 //! Set the internal bond index 107 /** \warning This will not update the index in the parent OBMol. 108 Intended mainly for internal use. Use with care. **/ SetIdx(int idx)109 void SetIdx(int idx) { _idx = idx; } SetId(unsigned long id)110 void SetId(unsigned long id) { _id = id; } 111 //! Set the bond order to @p order (i.e., 1 = single, 2 = double, 5 = aromatic) 112 void SetBondOrder(int order); 113 //! Set the beginning atom of this bond to @p begin. Does not update @p begin. SetBegin(OBAtom * begin)114 void SetBegin(OBAtom *begin){ _bgn = begin; } 115 //! Set the ending atom of this bond to @p end. Does not update @p end. SetEnd(OBAtom * end)116 void SetEnd(OBAtom *end) { _end = end; } 117 //! Set the parent molecule to @p ptr. Does not update parent. SetParent(OBMol * ptr)118 void SetParent(OBMol *ptr) { _parent= ptr; } 119 //! Change the bond length to @p length, while keeping @p fixed stationary 120 void SetLength(OBAtom *fixed,double length); 121 //! Change the bond length to @p length, moving both atoms halfway 122 //! \since version 2.2 123 void SetLength(double length); 124 //! Set the main bond information (i.e., when creating a bond) 125 void Set(int index, OBAtom* begin,OBAtom* end,int order,int flags); 126 //! Mark that this bond is aromatic. Does not update atoms or validate. 127 void SetAromatic(bool value=true) { SET_OR_UNSET_FLAG(OB_AROMATIC_BOND); } 128 /** 129 * Mark that this bond has 2D "wedge" notation (i.e., goes in a positive 130 * Z direction from the beginning to end atoms) 131 */ 132 void SetWedge(bool value=true) { SET_OR_UNSET_FLAG(Wedge); } 133 /** 134 * Mark that this bond has 2D "hash" notation (i.e., goes in a negative 135 * Z direction from the beginning to end atoms) 136 */ 137 void SetHash(bool value=true) { SET_OR_UNSET_FLAG(Hash); } 138 /** 139 * Set the WedgeOrHash flag on a bond (??) 140 */ 141 void SetWedgeOrHash(bool value=true) { SET_OR_UNSET_FLAG(WedgeOrHash); } 142 //! Mark that this bond is in a ring. Primarily for internal use. 143 void SetInRing(bool value=true) { SET_OR_UNSET_FLAG(OB_RING_BOND); } 144 //! Mark that this bond indicates a ring closure when walking the molecule 145 /** \warning This is for internal use only. All closure bonds are marked 146 automatically by lazy evaluation when requesting 147 OBBond::IsClosure() **/ 148 void SetClosure(bool value=true) { SET_OR_UNSET_FLAG(OB_CLOSURE_BOND); } 149 //@} 150 151 //! \name Bond data request methods 152 //@{ 153 //! \return The unique bond index in a molecule. GetIdx()154 unsigned int GetIdx() const { return(_idx); } GetId()155 unsigned long GetId() const { return _id; } 156 //! \return The bond order for the bond GetBondOrder()157 unsigned int GetBondOrder() const { return(_order); } 158 //! \return The set of property flags defined for this bond. GetFlags()159 unsigned int GetFlags() const { return(_flags); } 160 //! \return The atom index for the end atom in this bond (from OBAtom::GetIdx() GetBeginAtomIdx()161 unsigned int GetBeginAtomIdx() const 162 { return (_bgn ? _bgn->GetIdx() : 0); } 163 //! \return The atom index for the end atom in this bond (from OBAtom::GetIdx() GetEndAtomIdx()164 unsigned int GetEndAtomIdx() const 165 { return (_end ? _end->GetIdx() : 0); } 166 //! \return The "beginning" atom for this bond GetBeginAtom()167 OBAtom *GetBeginAtom() { return(_bgn); } GetBeginAtom()168 const OBAtom *GetBeginAtom() const 169 { return(_bgn); } 170 //! \return The "end" atom for this bond GetEndAtom()171 OBAtom *GetEndAtom() { return(_end); } GetEndAtom()172 const OBAtom *GetEndAtom() const 173 { return(_end); } 174 //! \return The neighboring atom to @p ptr (i.e., the end if @p ptr is the start) 175 /** \warning If @p ptr is not part of the bond, the beginning atom 176 will always be returned **/ GetNbrAtom(OBAtom * ptr)177 OBAtom *GetNbrAtom(OBAtom *ptr) 178 { 179 return((ptr != _bgn)? _bgn : _end); 180 } 181 //! \return The enclosing OBMol for this bond, or NULL if none is defined. GetParent()182 OBMol *GetParent() {return(_parent);} 183 //! \return The expected "equilibrium" length based on the covalent radii and bond order 184 /** Length is given in Angstroms **/ 185 double GetEquibLength() const; 186 //! \return The current length of this bond in Angstroms 187 double GetLength() const; 188 //! \return The index to the neighboring atom of @p ptr (i.e., the end if @p ptr is the start) 189 /** \warning If @p ptr is not part of the bond, the beginning atom 190 index will always be returned **/ GetNbrAtomIdx(OBAtom * ptr)191 unsigned int GetNbrAtomIdx(OBAtom *ptr) 192 { 193 if (ptr!=_bgn) 194 return (_bgn ? _bgn->GetIdx() : 0); 195 else 196 return (_end ? _end->GetIdx() : 0); 197 } 198 //! Find the smallest ring containing this bond (returns a NULL pointer if none exists) 199 OBRing* FindSmallestRing() const; 200 //@} 201 202 //! \name property request methods 203 //@{ 204 //! \return Is the bond aromatic? 205 //! (Note that the two atoms of the bond may be aromatic, 206 //! but not the bond) 207 bool IsAromatic() const; 208 //! \return Is the bond part of a ring? 209 bool IsInRing() const; 210 //! \return Is the bond a rotatable bond? 211 /** Currently, this function classifies any bond with at least one heavy 212 atom, no sp-hybrid atoms (e.g., a triple bond somewhere) not in a ring 213 as a potential rotor if includeRingsBonds is false. If true, rotors in 214 rings with more than 3 atoms may be included. No other bond typing is attempted. 215 For more detailed rotor detection, check the OBRotorList and 216 OBRotorRules classes **/ 217 bool IsRotor(bool includeRingBonds=false); 218 /** \return Is the bond an amide link (i.e., between a carbonyl C and a N)? 219 No distinction is made between primary, secondary, and tertiary amides. **/ 220 bool IsPeriodic() const; 221 //! \return Is the bond within a periodic unit cell? 222 bool IsAmide(); 223 /** \return Is the bond a primary amide (i.e., between carbonyl C and a NH2)? 224 In versions prior to 2.3, this function incorrectly identified secondary amides. **/ 225 bool IsPrimaryAmide(); 226 /** \return Is the bond a secondary amide (i.e., between a carbonyl C and a NH1)? 227 In versions prior to 2.3, this function incorrectly identified tertiary amides. **/ 228 bool IsSecondaryAmide(); 229 //! \return Is the bond a teriary amide (i.e., between a carbonyl C and a NH0)? 230 //! \since version 2.3. 231 bool IsTertiaryAmide(); 232 //! \return Is the bond an ester link (i.e., between a carbonyl C and an O)? 233 bool IsEster(); 234 //! \return Is the bond a carbonyl C=O? 235 bool IsCarbonyl(); 236 //! \return Does this bond "close" a ring when walking the molecular graph? 237 bool IsClosure(); 238 /** \return Whether this bond is a "wedge" in 2D representations 239 (i.e., goes in a positive Z direction from the beginning to end atoms) **/ IsWedge()240 bool IsWedge() { return(HasFlag(OB_WEDGE_BOND)); } 241 /** \return Whether this bond is a "hash" in 2D representations 242 (i.e., goes in a negative Z direction from the beginning to end atoms) **/ IsHash()243 bool IsHash() { return(HasFlag(OB_HASH_BOND)); } 244 /** 245 * @return True if this bond is either a wedge or hash. 246 * @note: This is a separate bond type 247 * @since version 2.3 248 */ IsWedgeOrHash()249 bool IsWedgeOrHash() const { return(HasFlag(WedgeOrHash)); } 250 /** 251 * @return True if this bond is either a cis or trans. 252 * @since version 2.3 253 */ IsCisOrTrans()254 bool IsCisOrTrans() const { return(HasFlag(CisOrTrans)); } 255 256 //! \return whether the geometry around this bond "looks" unsaturated 257 bool IsDoubleBondGeometry(); 258 //@} 259 260 }; // class OBBond 261 262 //! A standard iterator over a vector of bonds 263 typedef std::vector<OBBond*>::iterator OBBondIterator; 264 265 }// namespace OpenBabel 266 267 #endif // OB_BOND_H 268 269 //! @file bond.h 270 //! @brief Handle bonds 271