RDKit
Open-source cheminformatics and machine learning.
Loading...
Searching...
No Matches
QueryAtom.h
Go to the documentation of this file.
1//
2// Copyright (C) 2001-2022 Greg Landrum and other RDKit contributors
3//
4// @@ All Rights Reserved @@
5// This file is part of the RDKit.
6// The contents are covered by the terms of the BSD license
7// which is included in the file license.txt, found at the root
8// of the RDKit source tree.
9//
10#include <RDGeneral/export.h>
11#ifndef RD_QUERYATOM_H
12#define RD_QUERYATOM_H
13
14#include <utility>
15#include "Atom.h"
16#include <Query/QueryObjects.h>
17#include <GraphMol/QueryOps.h>
18
19namespace RDKit {
20
21//! Class for storing atomic queries
22/*!
23 QueryAtom objects are derived from Atom objects, so they can be
24 added to molecules and the like, but they have much fancier
25 querying capabilities.
26
27 */
29 public:
31
32 QueryAtom() : Atom() {}
33 explicit QueryAtom(int num) : Atom(num), dp_query(makeAtomNumQuery(num)) {}
34 explicit QueryAtom(const Atom &other) : Atom(other) {
35 if (other.hasQuery()) {
36 dp_query = other.getQuery()->copy();
37 } else {
38 dp_query = makeAtomNumQuery(other.getAtomicNum());
39
40 if (other.getIsotope()) {
41 this->expandQuery(makeAtomIsotopeQuery(other.getIsotope()),
42 Queries::CompositeQueryType::COMPOSITE_AND);
43 }
44 if (other.getFormalCharge()) {
45 this->expandQuery(makeAtomFormalChargeQuery(other.getFormalCharge()),
46 Queries::CompositeQueryType::COMPOSITE_AND);
47 }
48 if (other.getNumRadicalElectrons()) {
49 this->expandQuery(
50 makeAtomNumRadicalElectronsQuery(other.getNumRadicalElectrons()),
51 Queries::CompositeQueryType::COMPOSITE_AND);
52 }
53 }
54 }
55 QueryAtom(const QueryAtom &other) : Atom(other) {
56 if (other.dp_query) {
57 dp_query = other.dp_query->copy();
58 } else {
59 dp_query = nullptr;
60 }
61 }
62 QueryAtom &operator=(const QueryAtom &other) {
63 if (this == &other) {
64 return *this;
65 }
66 Atom::operator=(other);
67 delete dp_query;
68 if (other.dp_query) {
69 dp_query = other.dp_query->copy();
70 } else {
71 dp_query = nullptr;
72 }
73 return *this;
74 }
75
76 QueryAtom(QueryAtom &&other) noexcept : Atom(std::move(other)) {
77 dp_query = std::exchange(other.dp_query, nullptr);
78 }
79 QueryAtom &operator=(QueryAtom &&other) noexcept {
80 if (this == &other) {
81 return *this;
82 }
83 QueryAtom::operator=(std::move(other));
84 dp_query = std::exchange(other.dp_query, nullptr);
85 return *this;
86 }
87
88 ~QueryAtom() override;
89
90 //! returns a copy of this query, owned by the caller
91 Atom *copy() const override;
92
93 // This method can be used to distinguish query atoms from standard atoms:
94 bool hasQuery() const override { return dp_query != nullptr; }
95
96 //! returns the label associated to this query
97 std::string getQueryType() const override { return dp_query->getTypeLabel(); }
98
99 //! replaces our current query with the value passed in
100 void setQuery(QUERYATOM_QUERY *what) override {
101 delete dp_query;
102 dp_query = what;
103 }
104 //! returns our current query
105 QUERYATOM_QUERY *getQuery() const override { return dp_query; }
106
107 //! expands our current query
108 /*!
109 \param what the Queries::Query to be added. The ownership of
110 the query is passed to the current object, where it
111 might be deleted, so that the pointer should not be
112 used again in the calling code.
113 \param how the operator to be used in the expansion
114 \param maintainOrder (optional) flags whether the relative order of
115 the queries needs to be maintained, if this is
116 false, the order is reversed
117 <b>Notes:</b>
118 - \c what should probably be constructed using one of the functions
119 defined in QueryOps.h
120 - the \c maintainOrder option can be useful because the combination
121 operators short circuit when possible.
122
123 */
126 bool maintainOrder = true) override;
127
128 //! returns true if we match Atom \c what
129 bool Match(Atom const *what) const override;
130
131 //! returns true if our query details match those of QueryAtom \c what
132 bool QueryMatch(QueryAtom const *what) const;
133
134 private:
135 QUERYATOM_QUERY *dp_query{nullptr};
136
137}; // end o' class
138
139namespace detail {
140inline std::string qhelper(const Atom::QUERYATOM_QUERY *q, unsigned int depth) {
141 std::string res = "";
142 if (q) {
143 for (unsigned int i = 0; i < depth; ++i) {
144 res += " ";
145 }
146 res += q->getFullDescription() + "\n";
147 for (const auto &child :
148 boost::make_iterator_range(q->beginChildren(), q->endChildren())) {
149 res += qhelper(child.get(), depth + 1);
150 }
151 }
152 return res;
153}
154} // namespace detail
155inline std::string describeQuery(const Atom *atom) {
156 PRECONDITION(atom, "bad atom");
157 std::string res = "";
158 if (atom->hasQuery()) {
159 res = detail::qhelper(atom->getQuery(), 0);
160 }
161 return res;
162}
163
166
167}; // namespace RDKit
168
169#endif
Defines the Atom class and associated typedefs.
#define PRECONDITION(expr, mess)
Definition Invariant.h:108
Pulls in all the query types.
Base class for all queries.
Definition Query.h:48
virtual std::string getFullDescription() const
returns a fuller text description
Definition Query.h:75
CHILD_VECT_CI endChildren() const
returns an iterator for the end of our child vector
Definition Query.h:112
CHILD_VECT_CI beginChildren() const
returns an iterator for the beginning of our child vector
Definition Query.h:110
virtual Query< MatchFuncArgType, DataFuncArgType, needsConversion > * copy() const
returns a copy of this Query
Definition Query.h:136
The class for representing atoms.
Definition Atom.h:75
Atom & operator=(const Atom &other)
Queries::Query< int, Atom const *, true > QUERYATOM_QUERY
Definition Atom.h:90
unsigned int getNumRadicalElectrons() const
returns the number of radical electrons for this Atom
Definition Atom.h:208
virtual bool hasQuery() const
Definition Atom.h:269
int getFormalCharge() const
returns the formal charge of this atom
Definition Atom.h:212
virtual QUERYATOM_QUERY * getQuery() const
returns nullptr
bool hasQuery() const override
Definition QueryAtom.h:94
bool QueryMatch(QueryAtom const *what) const
returns true if our query details match those of QueryAtom what
QueryAtom & operator=(const QueryAtom &other)
Definition QueryAtom.h:62
void setQuery(QUERYATOM_QUERY *what) override
replaces our current query with the value passed in
Definition QueryAtom.h:100
QueryAtom(int num)
Definition QueryAtom.h:33
QueryAtom(QueryAtom &&other) noexcept
Definition QueryAtom.h:76
bool Match(Atom const *what) const override
returns true if we match Atom what
Queries::Query< int, Atom const *, true > QUERYATOM_QUERY
Definition QueryAtom.h:30
QueryAtom & operator=(QueryAtom &&other) noexcept
Definition QueryAtom.h:79
QueryAtom(const QueryAtom &other)
Definition QueryAtom.h:55
QueryAtom(const Atom &other)
Definition QueryAtom.h:34
~QueryAtom() override
void expandQuery(QUERYATOM_QUERY *what, Queries::CompositeQueryType how=Queries::COMPOSITE_AND, bool maintainOrder=true) override
expands our current query
std::string getQueryType() const override
returns the label associated to this query
Definition QueryAtom.h:97
QUERYATOM_QUERY * getQuery() const override
returns our current query
Definition QueryAtom.h:105
Atom * copy() const override
returns a copy of this query, owned by the caller
#define RDKIT_GRAPHMOL_EXPORT
Definition export.h:321
@ COMPOSITE_AND
std::string qhelper(const Atom::QUERYATOM_QUERY *q, unsigned int depth)
Definition QueryAtom.h:140
Std stuff.
RDKIT_GRAPHMOL_EXPORT bool hasUninitializedRecursiveQuery(const Atom &atom)
std::string describeQuery(const Atom *atom)
Definition QueryAtom.h:155
RDKIT_GRAPHMOL_EXPORT bool hasRecursiveQuery(const Atom &atom)
T * makeAtomNumQuery(int what, const std::string &descr)
returns a Query for matching atomic number
Definition QueryOps.h:400