Coverage Report

Created: 2026-07-30 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openbabel/include/openbabel/atom.h
Line
Count
Source
1
/**********************************************************************
2
atom.h - Handle OBAtom 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
8
This file is part of the Open Babel project.
9
For more information, see <http://openbabel.org/>
10
11
This program is free software; you can redistribute it and/or modify
12
it under the terms of the GNU General Public License as published by
13
the Free Software Foundation version 2 of the License.
14
15
This program is distributed in the hope that it will be useful,
16
but WITHOUT ANY WARRANTY; without even the implied warranty of
17
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
GNU General Public License for more details.
19
***********************************************************************/
20
21
#ifndef OB_ATOM_H
22
#define OB_ATOM_H
23
24
#include <openbabel/babelconfig.h>
25
26
#ifndef OB_EXTERN
27
#  define OB_EXTERN extern
28
#endif
29
30
#include <vector>
31
#include <string>
32
33
#include <openbabel/base.h>
34
#include <openbabel/residue.h>
35
#include <openbabel/math/vector3.h>
36
37
namespace OpenBabel
38
{
39
40
  class OBBond;
41
  class OBMol;
42
43
  //! OBNodeBase is declared for backwards-compatibility with 2.0 and earlier code
44
  typedef OBAtom OBNodeBase;
45
  //! A standard iterator over a vector of bonds
46
  typedef std::vector<OBBond*>::iterator OBBondIterator;
47
  //! A standard iterator over a vector of atoms
48
  typedef std::vector<OBAtom*>::iterator OBAtomIterator;
49
50
  //ATOM Property Macros (flags)
51
  //! Atom is in a 4-membered ring
52
#define OB_4RING_ATOM     (1<<1)
53
  //! Atom is in a 3-membered ring
54
#define OB_3RING_ATOM     (1<<2)
55
  //! Atom is aromatic
56
160M
#define OB_AROMATIC_ATOM  (1<<3)
57
  //! Atom is in a ring
58
292M
#define OB_RING_ATOM      (1<<4)
59
  //! Atom is an electron donor
60
#define OB_DONOR_ATOM     (1<<7)
61
  //! Atom is an electron acceptor
62
#define OB_ACCEPTOR_ATOM  (1<<8)
63
64
#define SET_OR_UNSET_FLAG(X) \
65
147M
  if (value) SetFlag(X); \
66
147M
  else     UnsetFlag(X);
67
68
  class OBAPI OBAtomAtomIterAdaptor
69
  {
70
    public:
71
      using Iter = std::vector<OBBond*>::const_iterator;
72
73
      using value_type = OBAtom*;
74
      using difference_type = std::ptrdiff_t;
75
      using pointer = OBAtom**;
76
      using reference = OBAtom*&;
77
      using iterator_category = std::forward_iterator_tag;
78
79
      OBAtomAtomIterAdaptor() = default;
80
81
      OBAtomAtomIterAdaptor(Iter iter, const OBAtom *atom = nullptr)
82
40.4M
        : m_iter(iter), m_atom(atom)
83
40.4M
      {
84
40.4M
      }
85
86
      OBAtom* operator*() const;
87
88
      OBAtomAtomIterAdaptor& operator++()
89
96.7M
      {
90
96.7M
        ++m_iter;
91
96.7M
        return *this;
92
96.7M
      }
93
94
      OBAtomAtomIterAdaptor operator++(int)
95
0
      {
96
0
        auto tmp = *this;
97
0
        ++m_iter;
98
0
        return tmp;
99
0
      }
100
101
      bool operator==(const OBAtomAtomIterAdaptor &other) const
102
0
      {
103
0
        return m_iter == other.m_iter;
104
0
      }
105
106
      bool operator!=(const OBAtomAtomIterAdaptor &other) const
107
116M
      {
108
116M
        return m_iter != other.m_iter;
109
116M
      }
110
111
    private:
112
      Iter m_iter;
113
      const OBAtom *m_atom = nullptr;
114
  };
115
116
  using OBAtomBondRange = OBRange<OBBond*>;
117
  using OBAtomAtomRange = OBRange<OBAtom*, OBAtomAtomIterAdaptor>;
118
119
#if __cplusplus >= 202002L
120
  static_assert(std::forward_iterator<OBAtomAtomIterAdaptor>);
121
  static_assert(std::ranges::range<OBAtomAtomRange>);
122
#endif
123
124
  // Class OBAtom
125
  // class introduction in atom.cpp
126
6.96k
 #define OBATOM_TYPE_LEN 6
127
 class OBAPI OBAtom: public OBBase
128
    {
129
    protected:
130
      unsigned char                 _ele;       //!< atomic number (type unsigned char to minimize space -- allows for 0..255 elements)
131
      unsigned char                 _imph;      //!< number of implicit hydrogens
132
      char                          _type[OBATOM_TYPE_LEN];   //!< atomic type
133
      short                         _fcharge;   //!< formal charge
134
      unsigned short                _isotope;   //!< isotope (0 = most abundant)
135
      short                         _spinmultiplicity;//!< atomic spin, e.g., 2 for radical  1 or 3 for carbene
136
137
      unsigned int                  _idx;       //!< unique node index (GetIdx(), SetIdx())
138
      OBMol                        *_parent;    //!< parent molecule (if any)
139
      std::vector<OBBond*>          _vbond;     //!< bonds to this atom -- assumed to be one of the endpoints
140
141
      unsigned int                  _cidx;      //!< index into coordinate array
142
      unsigned short                _hyb;       //!< hybridization
143
      unsigned short                _flags;     //!< bitwise flags (e.g. aromaticity)
144
      double                        _pcharge;   //!< partial charge
145
      double                      **_c;         //!< coordinate array in double*
146
      mutable vector3               _v;         //!< coordinate vector
147
      OBResidue                    *_residue;   //!< parent residue (if applicable)
148
149
      unsigned long                 _id;        //!< unique id
150
151
      //! \return All flags
152
0
      int  GetFlag() const    {  return(_flags);  }
153
      //! Sets the bitwise @p flag
154
44.8M
      void SetFlag(int flag)  { _flags |= flag;   }
155
      //! Unsets the bitwise @p flag
156
102M
      void UnsetFlag(int flag) { _flags &= (~(flag)); }
157
      //! \return True of the atom has the @p flag
158
453M
      bool HasFlag(int flag)  {  return((_flags & flag) ? true : false); }
159
160
    public:
161
      enum StereoFlag {
162
163
      };
164
165
166
       //! Used internally by graph traversal algorithms
167
      bool Visit;
168
169
      //! Constructor
170
      OBAtom();
171
      //! Destructor
172
      virtual ~OBAtom();
173
      //! Assignment
174
      OBAtom &operator = (OBAtom &);
175
      //! Equivalence
176
0
      bool operator==(const OBAtom * other) const {  return (GetIdx() == other->GetIdx()); }
177
      //! Duplicate another atom. Copies all information with the exception of index
178
      //! \since version 2.2
179
      void Duplicate(OBAtom *);
180
      //! Clear all data. Calls OBBase::Clear() to handle any generic data.
181
      //! \return True if successful.
182
      bool Clear();
183
184
      //! \name Methods to set atomic information
185
      //@{
186
      //! Set atom index (i.e., in an OBMol)
187
1.75G
      void SetIdx(int idx)    { _idx = idx; _cidx = (idx-1)*3; }
188
82.3M
      void SetId(unsigned long id) { _id = id; }
189
      //! Set atom hybridization (i.e., 1 = sp, 2 = sp2, 3 = sp3 ...)
190
21.1M
      void SetHyb(int hyb)    { _hyb = hyb; }
191
      //! Set atomic number
192
68.3M
      void SetAtomicNum(int atomicnum)    { _ele = (char)atomicnum; }
193
      //! Set isotope number (actual atomic weight is tabulated automatically, 0 = most abundant)
194
      void SetIsotope(unsigned int iso);
195
      //! Set the implicit hydrogen count to @p val
196
56.0M
      void SetImplicitHCount(unsigned int val)    { _imph = (unsigned char)val; }
197
      //! Set the formal charge of the atom to @p fcharge
198
241k
      void SetFormalCharge(int fcharge)   { _fcharge = fcharge; }
199
      //! Set the atomic spin to @p spin. See _spinmultiplicity
200
1.90M
      void SetSpinMultiplicity(short spin){ _spinmultiplicity = spin; }
201
      //! Set the atomic type symbol (see OBTypeTable and OBAtomTyper for more)
202
      void SetType(const char *type);
203
      //! Set the atomic type symbol (see OBTypeTable and OBAtomTyper for more)
204
      void SetType(const std::string &type);
205
      //! Set the partial charge to @p pcharge
206
509k
      void SetPartialCharge(double pcharge){ _pcharge = pcharge; }
207
      //! Set the coordinate vector for this atom to @p v as a vector3
208
      void SetVector(const vector3 &v);
209
      //! Set the coordinate vector for this atom based on @p x @p y & @p z
210
      void SetVector(const double x,const double y,const double z);
211
      //! Set the position of this atom from a pointer-driven array of coordinates
212
1.67G
      void SetCoordPtr(double **c)        { _c = c; _cidx = GetIdx() ? (GetIdx()-1)*3 : 0; }
213
      //! Set the position of this atom based on the internal pointer array (i.e. from SetCoordPtr() )
214
      void SetVector();
215
      //! Attach an OBResidue @p res as containing this atom
216
3.98M
      void SetResidue(OBResidue *res)     { _residue=res; }
217
      //! Attach an OBMol @p ptr as the parent container for this atom
218
82.3M
      void SetParent(OBMol *ptr)          { _parent=ptr; }
219
      //! Mark atom as being aromatic
220
83.1M
      void SetAromatic(bool value=true)                  { SET_OR_UNSET_FLAG(OB_AROMATIC_ATOM); }
221
      //! Mark an atom as belonging to at least one ring
222
64.6M
      void SetInRing(bool value=true)         { SET_OR_UNSET_FLAG(OB_RING_ATOM); }
223
      //! Clear the internal coordinate pointer
224
1.59G
      void ClearCoordPtr()     { _c = nullptr; _cidx=0; }
225
      //@}
226
227
      //! \name Methods to retrieve atomic information
228
      //@{
229
      //! \return the formal charge for this atom
230
118M
      int          GetFormalCharge()  const { return(_fcharge);    }
231
      //! \return the atomic number for this atom
232
1.46G
      unsigned int GetAtomicNum()     const { return((unsigned int)_ele); }
233
      //! \return the isotope for this atom, if specified, or 0 for unspecified
234
50.6M
      unsigned short int GetIsotope() const { return(_isotope);    }
235
      //! \return the atomic spin, e.g., 0 (default) for normal atoms - note that this value is a convention,
236
      //!   2 for radical  1 or 3 for carbene
237
63.0M
      int          GetSpinMultiplicity() const { return(_spinmultiplicity); }
238
      //! \return the atomic mass of this atom given by standard IUPAC
239
      //!  average molar mass
240
      double     GetAtomicMass()    const;
241
      //! \return the atomic mass of this atom given by the isotope
242
      //! (default of 0 gives the most abundant isotope)
243
      double     GetExactMass()     const;
244
      //! \return the internal atom index (e.g., inside an OBMol)
245
7.31G
      unsigned int GetIdx()           const { return((int)_idx);  }
246
1.51G
      unsigned int GetIndex() const { return _idx - 1; }
247
96.1M
      unsigned long GetId() const { return _id; }
248
      //! \return the index into a pointer-driven array as used by
249
      //!   GetCoordPtr() or SetCoordPtr()
250
480k
      unsigned int GetCoordinateIdx() const { return((int)_cidx); }
251
      //! \return The number of explicit bonds to this atom
252
67.6M
      unsigned int GetExplicitDegree() const { return (unsigned int)_vbond.size(); }
253
      //! \return The total number of bonds to this atom including bonds to implicit hydrogens
254
27.4M
      unsigned int GetTotalDegree() const { return (unsigned int)(_vbond.size() + _imph); }
255
      //! \return The sum of the bond orders of the explicit bonds to this atom
256
      unsigned int GetExplicitValence() const;
257
      //! \return The sum of the bond orders of all bonds to this atom including bonds to implicit hydrogens
258
      unsigned int GetTotalValence() const;
259
      //! \return The hybridization of this atom: 1 for sp, 2 for sp2, 3 for sp3, 4 for sq. planar, 5 for trig. bipy, 6 for octahedral
260
      unsigned int GetHyb()             const;
261
      //! \return The number of implicit hydrogens attached to this atom
262
78.5M
      unsigned char GetImplicitHCount() const { return _imph; };
263
      //! \return The number of non-hydrogens connected to this atom
264
      unsigned int GetHvyDegree()      const;
265
      //! \return The number of heteroatoms connected to an atom
266
      unsigned int GetHeteroDegree()   const;
267
      //! \return the atomic type (e.g., for molecular mechanics)
268
      char        *GetType();
269
270
      //! \return the x coordinate
271
475M
      double      GetX() const   {        return(x());    }
272
      //! \return the y coordinate
273
475M
      double      GetY() const  {        return(y());    }
274
      //! \return the z coordinate
275
475M
      double      GetZ() const  {        return(z());    }
276
277
      // These methods check to see if there is a coordinate pointer
278
      // or an internal vector (e.g., SetCoordPtr())
279
      //! \return the x coordinate
280
477M
      double      x() const {
281
477M
        if (_c)            return((*_c)[_cidx]);
282
474M
        else               return _v.x();
283
477M
      }
284
      //! \return the y coordinate
285
477M
      double      y() const {
286
477M
        if (_c)            return((*_c)[_cidx+1]);
287
474M
        else               return _v.y();
288
477M
      }
289
      //! \return the z coordinate
290
476M
      double      z() const {
291
476M
        if (_c)            return((*_c)[_cidx+2]);
292
474M
        else               return _v.z();
293
476M
      }
294
      //! \return the coordinates as a double* or NULL if none.
295
      //!
296
      //! See SetCoordPtr() for more. If no coordinate pointer is used
297
      //! (e.g., only vector3), NULL will be returned.
298
0
      double     *GetCoordinate(){
299
0
        if (_c)          return(&(*_c)[_cidx]);
300
0
        else             return nullptr;
301
0
      }
302
      //! \return the coordinates as a vector3 object
303
      vector3   &GetVector();
304
      //! \return the coordinates as a vector3 object
305
      const vector3   &GetVector() const;
306
      //! \return the partial charge of this atom, calculating a Gasteiger charge if needed
307
      double     GetPartialCharge();
308
      //! \return the residue which contains this atom, or NULL if none exists
309
      OBResidue *GetResidue();
310
      //! \return the molecule which contains this atom, or NULL if none exists
311
991M
      OBMol     *GetParent()        {return((OBMol*)_parent);}
312
      //! Create a vector for a new bond from this atom, with length given by the supplied parameter
313
      //! \return success or failure
314
      bool       GetNewBondVector(vector3 &v,double length);
315
      //! \return the OBBond object between this atom and that supplied,
316
      //! or NULL if the two atoms are not bonded
317
      OBBond    *GetBond(OBAtom *);
318
      //@}
319
320
      //! \name Iterator methods
321
      //@{
322
      //! \return An iterator to the beginning of the bonds to this atom
323
      OBBondIterator BeginBonds()
324
31
        { return(_vbond.begin()); }
325
      //! \return An iterator to the end of the bonds to this atom
326
      OBBondIterator EndBonds()
327
0
        { return(_vbond.end());   }
328
      //! \return A range over the bonds to this atom. This range can be used in a range-based for loop.
329
276M
      OBAtomBondRange GetBonds() const { return {_vbond.begin(), _vbond.end()}; }
330
      //! Set the iterator @p i to the beginning of the bonds
331
      //! \return The first bond to this atom (or NULL if none exist)
332
      OBBond *BeginBond(OBBondIterator &i);
333
      //! Increment the iterator @p i
334
      //! \return The next bond to this atom (or NULL if none exist)
335
      OBBond *NextBond(OBBondIterator &i);
336
      //! \return A range over the neighbors of this atom. This range can be used in a range-based for loop.
337
20.2M
      OBAtomAtomRange GetNbrs() const { return { {_vbond.begin(), this}, {_vbond.end()} }; }
338
      //! Set the iterator @p i to the beginning of the bonds
339
      //! \return The first neighboring atom (or NULL if none exist)
340
      OBAtom *BeginNbrAtom(OBBondIterator &i);
341
      //! Increment the iterator @p i
342
      //! \return The next neighboring atom (or NULL if none exist)
343
      OBAtom *NextNbrAtom(OBBondIterator &i);
344
      //@}
345
346
      //! \return the distance to the atom defined by OBMol::GetAtom()
347
      double GetDistance(int index);
348
      //! \return the distance to the supplied OBAtom
349
      double GetDistance(OBAtom*);
350
      //! \return the distance to the coordinates of the supplied vector3
351
      //! \since version 2.4
352
      double GetDistance(vector3* v);
353
      //! \return the angle defined by this atom -> b (vertex) -> c
354
      double GetAngle(int b, int c);
355
      //! \return the angle defined by this atom -> b (vertex) -> c
356
      double GetAngle(OBAtom *b, OBAtom *c);
357
358
      //! \name Addition of residue/bond info. for an atom
359
      //@{
360
361
      //! If no residue has been set for this atom, create a new one
362
      void NewResidue()
363
0
        {
364
0
          if (!_residue)
365
0
            _residue = new OBResidue;
366
0
        }
367
      //! Add (set) the residue for this atom
368
0
      void AddResidue(OBResidue *res) { SetResidue(res); }
369
      //! Delete any residue associated with this atom
370
0
      void DeleteResidue(){
371
0
        if (_residue) {
372
0
          delete _residue;
373
0
          _residue = nullptr; // Make sure to clear that a residue existed
374
0
        }
375
0
      }
376
      //! Add a bond to the internal list. Does not update the bond.
377
168M
      void AddBond(OBBond *bond) { _vbond.push_back(bond); }
378
      //! \brief Insert @p bond into the internal list at the position from @p i
379
      //! Does not modify the bond
380
      void InsertBond(OBBondIterator &i, OBBond *bond)
381
714k
        {
382
714k
          _vbond.insert(i, bond);
383
714k
        }
384
      //! Find @p bond and remove it from the internal list. Does not update the bond.
385
      bool DeleteBond(OBBond* bond);
386
      //! Clear all bonding information in this atom (does not delete them)
387
0
      void ClearBond() {_vbond.clear();}
388
      //@}
389
390
      //! \name Builder utilities
391
      //@{
392
393
      //! \brief If this is a hydrogen atom, transform into a methyl group
394
      //! \return success or failure
395
      bool HtoMethyl();
396
      //! Change the hybridization of this atom and modify the geometry accordingly
397
      //! \return success or failure
398
      //! \deprecated This will be removed in future versions of Open Babel
399
      OB_DEPRECATED bool SetHybAndGeom(int);
400
      //@}
401
402
      //! \name Property information
403
      //@{
404
      //! \return The number of oxygen atoms connected that only have one heavy valence
405
      unsigned int  CountFreeOxygens()      const;
406
      //! \return The number of sulfur atoms connected that only have one heavy valence
407
      //! \since version 2.4
408
      unsigned int  CountFreeSulfurs()      const;
409
      //! \return The number of hydrogens explicitly bound to this atom, optionally excluding D,T and isotope explicitly set to 1
410
      unsigned int  ExplicitHydrogenCount(bool ExcludeIsotopes=false) const;
411
      //! \return The number of rings that contain this atom
412
      unsigned int  MemberOfRingCount()     const;
413
      //! \return The size of the smallest ring that contains this atom (0 if not in a ring)
414
      unsigned int  MemberOfRingSize()    const;
415
      //! \return The number of explicit ring connections to this atom
416
      unsigned int  CountRingBonds() const;
417
      //! \return The smallest angle of bonds to this atom
418
      double    SmallestBondAngle();
419
      //! \return The average angle of bonds to this atom
420
      double    AverageBondAngle();
421
      /** Lewis acid/base vacancies for this atom
422
       *  \return A pair of integers, where first is acid count and second is base count
423
       *  \since version 2.3
424
       */
425
      std::pair<int, int> LewisAcidBaseCounts() const;
426
      //! \return Is there any residue information?
427
3.71M
      bool HasResidue()    { return(_residue != nullptr);    }
428
      //! \return Is this a HETATM in a residue (returns false if not in a residue)
429
      //! \since version 2.4
430
0
      bool IsHetAtom() {
431
0
        if (_residue == nullptr)
432
0
          return false;
433
0
        else
434
0
          return _residue->IsHetAtom(this);
435
0
      }
436
      //! \return Is the specified element, as specified by atom number (see OBElement namespace)?
437
0
      bool IsElement(const unsigned int e) const {
438
0
           return e == _ele;
439
0
      }
440
      //! \return Is the atom aromatic?
441
      bool IsAromatic()      const;
442
      //! \return Is the atom in a ring?
443
      bool IsInRing()        const;
444
      //! \return Is the atom in a ring of a given size?
445
      bool IsInRingSize(int) const;
446
      //! \return Is this atom an element in the 15th or 16th main groups
447
      //!  (i.e., N, O, P, S ...) ?
448
      bool IsHeteroatom();
449
      //! \return Is this atom directly connected to the supplied OBAtom?
450
      bool IsConnected(OBAtom*);
451
      //! \return Is this atom related to the supplied OBAtom in
452
      //!  a 1,3 bonding pattern?
453
      bool IsOneThree(OBAtom*);
454
      //! \return Is this atom related to the supplied OBAtom in
455
      //!  a 1,4 bonding pattern?
456
      bool IsOneFour(OBAtom*);
457
      //! \return Is this atom an oxygen in a carboxyl (-CO2 or CO2H) group?
458
      bool IsCarboxylOxygen();
459
      //! \return Is this atom an oxygen in a phosphate (R-PO3) group?
460
      bool IsPhosphateOxygen();
461
      //! \return Is this atom an oxygen in a sulfate (-SO3) group?
462
      bool IsSulfateOxygen();
463
      //! \return Is this atom an oxygen in a nitro (-NO2) group?
464
      bool IsNitroOxygen();
465
      //! \return Is this atom a nitrogen in an amide (-C(=O)NR2) group?
466
      bool IsAmideNitrogen();
467
      //! \return Is this atom a hydrogen connected to a polar atom
468
      //!  (i.e., N, O, P, S)
469
      bool IsPolarHydrogen();
470
      //! \return Is this atom a hydrogen connected to a non-polar atom
471
      //!  (i.e., C)
472
      bool IsNonPolarHydrogen();
473
      //! \return Is this atom an aromatic nitrogen with at least one
474
      //!  double bond to an oxygen atom
475
      bool IsAromaticNOxide();
476
      //! \return Is this atom chiral?
477
      bool IsChiral();
478
      //! \return Is the atom part of a periodic unit cell?
479
      bool IsPeriodic() const;
480
      //! \return Is this atom an axial atom in a ring
481
      bool IsAxial();
482
      //! \return Is this atom a hydrogen-bond acceptor  (considering also atom surrounding)
483
      bool IsHbondAcceptor();
484
      //! \return Is this atom a hydrogen-bond acceptor (old function)?
485
      bool IsHbondAcceptorSimple();
486
            //! \return Is this atom a hydrogen-bond donor?
487
      bool IsHbondDonor();
488
      //! \return Is this a hydrogen atom attached to a hydrogen-bond donor?
489
      bool IsHbondDonorH();
490
      //! \return Is this atom a metal?
491
      //! \since version 2.4
492
      bool IsMetal();
493
      //! \return Whether a neighboring atom (alpha) has an unsaturated bond
494
      //!   to a third atom (beta).
495
      //! \param includePandS Whether to include phosphorus and sulfur neighbors
496
      //! in this determination (or to exclude them)
497
      bool HasAlphaBetaUnsat(bool includePandS=true);
498
      //! \return Whether this atom is connected to any bond with order == @p bo
499
      bool HasBondOfOrder(unsigned int bo);
500
      //! \return The count of bonds connected to this atom with order == @p bo
501
      int  CountBondsOfOrder(unsigned int bo);
502
      //! \return The maximum bond order for this atom
503
      int  HighestBondOrder();
504
      //! \return Whether this atom is connected to any bond with order >1
505
      bool HasNonSingleBond();
506
      //! \return Does this atom have a single bond
507
181k
      bool HasSingleBond()    {        return(HasBondOfOrder(1));    }
508
      //! \return Does this atom have a double bond
509
507k
      bool HasDoubleBond()    {        return(HasBondOfOrder(2));    }
510
      //! \return Does this atom have an aromatic bond
511
0
      bool HasAromaticBond()  {        return(HasBondOfOrder(5));    }
512
      //! \return Whether this atom matches the first atom in a given SMARTS pattern
513
      bool MatchesSMARTS(const char *);
514
      //@}
515
516
    }; // class OBAtom
517
518
}// namespace OpenBabel
519
520
#endif   // OB_ATOM_H
521
522
//! \file atom.h
523
//! \brief Handle atoms