Coverage Report

Created: 2025-07-13 06:40

/src/openbabel/include/openbabel/query.h
Line
Count
Source (jump to first uncovered line)
1
/**********************************************************************
2
  query.h - OBQuery, OBQueryAtom & OBQueryBond classes.
3
4
  Copyright (C) 2010 by Tim Vandermeersch
5
6
  This file is part of the Open Babel project.
7
  For more information, see <http://openbabel.org/>
8
9
  This program is free software; you can redistribute it and/or modify
10
  it under the terms of the GNU General Public License as published by
11
  the Free Software Foundation; either version 2 of the License, or
12
  (at your option) any later version.
13
14
  This program is distributed in the hope that it will be useful,
15
  but WITHOUT ANY WARRANTY; without even the implied warranty of
16
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
  GNU General Public License for more details.
18
19
  You should have received a copy of the GNU General Public License
20
  along with this program; if not, write to the Free Software
21
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22
  02110-1301, USA.
23
 **********************************************************************/
24
#ifndef OB_QUERY_H
25
#define OB_QUERY_H
26
27
#include <openbabel/bond.h> // TODO: Move OBBond code out of this header
28
#include <openbabel/bitvec.h>
29
#include <openbabel/tokenst.h>
30
31
namespace OpenBabel {
32
33
  class OBQueryBond;
34
  class OBMol;
35
36
  ///@addtogroup substructure Substructure Searching
37
  ///@{
38
39
  /**
40
   * @class OBQueryAtom query.h <openbabel/query.h>
41
   * @brief Atom in an OBQuery
42
   *
43
   * The OBQueryAtom class defines an interface for query atoms. The class provides
44
   * some general methods and properties to access the topology information. The Matches
45
   * method can be reimplemented in subclasses to get custom matching behavior.
46
   *
47
   * The default Matches implementation only checks the atomic number.
48
   *
49
   * See @ref substructure for more information.
50
   *
51
   * @sa OBQuery OBQueryBond OBIsomorphismMapper
52
   * @since version 2.3
53
   */
54
  class OBAPI OBQueryAtom
55
  {
56
    public:
57
      friend class OBQuery;
58
      friend class OBQueryBond;
59
      /**
60
       * Constructor.
61
       * @param atomicNum The atomic number for this query atom.
62
       * @param isInRing Specify whether the query atom is in a ring. Default is false.
63
       * @param isAromatic Specify whether the query atom is aromatic. Default is false.
64
       */
65
      OBQueryAtom(int atomicNum = 6, bool isInRing = false, bool isAromatic = false) :
66
0
        m_atomicNum(atomicNum), m_isInRing(isInRing), m_isAromatic(isAromatic) {}
67
68
0
      virtual ~OBQueryAtom() {}
69
70
      /**
71
       * Get the index for this query atom. Atoms are indexed starting from 0.
72
       * This method is used by OBIsomorphismMapper implementations.
73
       */
74
      unsigned int GetIndex() const
75
0
      {
76
0
        return m_index;
77
0
      }
78
      /**
79
       * Get the query bonds for this atom.
80
       * This method is used by OBIsomorphismMapper implementations.
81
       */
82
      const std::vector<OBQueryBond*>& GetBonds() const
83
0
      {
84
0
        return m_bonds;
85
0
      }
86
      /**
87
       * Get the neighbor query atoms.
88
       * This method is used by OBIsomorphismMapper implementations.
89
       */
90
      const std::vector<OBQueryAtom*>& GetNbrs() const
91
0
      {
92
0
        return m_nbrs;
93
0
      }
94
      /**
95
       * This is the match method to verify if an OBQueryAtom and OBAtom class match.
96
       * The default implementation only checks if the atomic numbers match. Reimplement
97
       * this method in a subclass for more advances matching.
98
       * This method is used by OBIsomorphismMapper implementations.
99
       * @param atom The OBAtom object to compare this OBQueryAtom with.
100
       */
101
      virtual bool Matches(const OBAtom *atom) const
102
0
      {
103
0
        if (atom->GetAtomicNum() != m_atomicNum)
104
0
          return false;
105
0
        if (atom->IsAromatic() != m_isAromatic)
106
0
          return false;
107
0
        if (m_isInRing)
108
0
          if (!atom->IsInRing())
109
0
            return false;
110
0
        return true;
111
0
      }
112
    protected:
113
      unsigned int m_index;
114
      unsigned int m_atomicNum;
115
      bool m_isInRing, m_isAromatic;
116
      std::vector<OBQueryBond*> m_bonds;
117
      std::vector<OBQueryAtom*> m_nbrs;
118
  };
119
120
  /**
121
   * @class OBQueryBond query.h <openbabel/query.h>
122
   * @brief Bond in an OBQuery
123
   *
124
   * The OBQueryBond class defines an interface for query bonds. The class provides
125
   * some general methods and properties to access the topology information. The Matches
126
   * method can be reimplemented in subclasses to get custom matching behavior.
127
   *
128
   * The default Matches implementation only checks if the bonds are both aromatic,
129
   * otherwise the bond orders are compared.
130
   *
131
   * See @ref substructure for more information.
132
   *
133
   * @sa OBQuery OBQueryAtom OBIsomorphismMapper
134
   * @since version 2.3
135
   */
136
  class OBAPI OBQueryBond
137
  {
138
    public:
139
      friend class OBQuery;
140
      /**
141
       * Constructor.
142
       */
143
      OBQueryBond(OBQueryAtom *begin, OBQueryAtom *end, int order = 1, bool aromatic = false) :
144
0
          m_begin(begin), m_end(end), m_order(order), m_aromatic(aromatic)
145
0
      {
146
0
        m_begin->m_bonds.push_back(this);
147
0
        m_end->m_bonds.push_back(this);
148
0
        m_begin->m_nbrs.push_back(m_end);
149
0
        m_end->m_nbrs.push_back(m_begin);
150
0
      }
151
152
0
      virtual ~OBQueryBond() {}
153
154
      /**
155
       * Get the index for this query bonds. Query bonds are indexed starting from 0.
156
       */
157
      unsigned int GetIndex() const
158
0
      {
159
0
        return m_index;
160
0
      }
161
      /**
162
       * Get the begin atom.
163
       */
164
0
      OBQueryAtom* GetBeginAtom() const { return m_begin; }
165
      /**
166
       * Get the end atom.
167
       */
168
0
      OBQueryAtom* GetEndAtom() const { return m_end; }
169
      /**
170
       * This is the match method to verify if an OBQueryBond and OBBond class match.
171
       * The default implementation checks if both bonds are aromatic and compares the
172
       * bond orders otherwise. Reimplement this method in a subclass for more
173
       * advances matching.
174
       * This method is used by OBIsomorphismMapper implementations.
175
       * @param bond The OBBond object to compare this OBQueryBond with.
176
       */
177
      virtual bool Matches(const OBBond *bond) const
178
0
      {
179
0
        if (m_aromatic)
180
0
          return bond->IsAromatic();
181
0
        return bond->GetBondOrder() == m_order;
182
0
      }
183
    protected:
184
      unsigned int m_index;
185
      OBQueryAtom *m_begin, *m_end;
186
      unsigned int m_order;
187
      bool m_aromatic;
188
  };
189
190
  /**
191
   * @class OBQuery query.h <openbabel/query.h>
192
   * @brief A substructure query
193
   *
194
   * See @ref substructure for more information.
195
   * @since version 2.3
196
   */
197
  class OBAPI OBQuery
198
  {
199
    public:
200
      ~OBQuery();
201
      /**
202
       * @return The number of atoms in the query.
203
       */
204
      unsigned int NumAtoms() const
205
0
      {
206
0
        return m_atoms.size();
207
0
      }
208
      /**
209
       * @return The number of bonds in the query.
210
       */
211
      unsigned int NumBonds() const
212
0
      {
213
0
        return m_bonds.size();
214
0
      }
215
      /**
216
       * @return std::vector with pointers to the query atoms.
217
       */
218
      const std::vector<OBQueryAtom*>& GetAtoms() const
219
0
      {
220
0
        return m_atoms;
221
0
      }
222
      /**
223
       * @return std::vector with pointers to the query bonds.
224
       */
225
      const std::vector<OBQueryBond*>& GetBonds() const
226
0
      {
227
0
        return m_bonds;
228
0
      }
229
      /**
230
       * @return The query bond between @p begin and @p end. If there is no
231
       * bond between @p begin and @p end, this function returns 0.
232
       */
233
      OBQueryBond* GetBond(OBQueryAtom *begin, OBQueryAtom *end) const
234
0
      {
235
0
        for (unsigned int i = 0; i < begin->GetBonds().size(); ++i)
236
0
          if (begin->GetNbrs()[i] == end)
237
0
            return begin->GetBonds()[i];
238
0
        return nullptr;
239
0
      }
240
      /**
241
       * Add a query atom to the query. This function steals the pointer.
242
       */
243
      void AddAtom(OBQueryAtom *atom)
244
0
      {
245
0
        atom->m_index = m_atoms.size();
246
0
        m_atoms.push_back(atom);
247
0
      }
248
      /**
249
       * Add a query atom to the query. This function steals the pointer.
250
       */
251
      void AddBond(OBQueryBond *bond)
252
0
      {
253
0
        bond->m_index = m_bonds.size();
254
0
        m_bonds.push_back(bond);
255
0
      }
256
    protected:
257
      std::vector<OBQueryAtom*> m_atoms;
258
      std::vector<OBQueryBond*> m_bonds;
259
  };
260
261
  /**
262
   * Create an OBQuery object from an OBMol object. 
263
   * @param mol The query molecule.
264
   * @param mask The mask specifying the atoms to use. Indexed from 1 (i.e. OBAtom::GetIdx()).
265
   * @return A pointer to an OBQuery object for the smiles string. This pointer should be deleted.
266
   * @since version 2.3
267
   */
268
  OBAPI OBQuery* CompileMoleculeQuery(OBMol *mol, const OBBitVec &mask = OBBitVec());
269
270
  /**
271
   * Create an OBQuery object from a smiles string. 
272
   * @param smiles The query smiles string.
273
   * @param mask The mask specifying the atoms to use. Indexed from 1 (i.e. OBAtom::GetIdx()).
274
   * @return A pointer to an OBQuery object for the smiles string. This pointer should be deleted.
275
   * @since version 2.3
276
   */
277
  OBAPI OBQuery* CompileSmilesQuery(const std::string &smiles, const OBBitVec &mask = OBBitVec());
278
279
  ///@}
280
}
281
282
#endif
283
284
/// @file query.h
285
/// @brief OBQuery, OBQueryAtom & OBQueryBond classes.