RDKit
Open-source cheminformatics and machine learning.
Loading...
Searching...
No Matches
Reaction.h
Go to the documentation of this file.
1//
2// Copyright (c) 2007-2021, Novartis Institutes for BioMedical Research Inc.
3// and other RDKit contributors
4//
5// All rights reserved.
6//
7// Redistribution and use in source and binary forms, with or without
8// modification, are permitted provided that the following conditions are
9// met:
10//
11// * Redistributions of source code must retain the above copyright
12// notice, this list of conditions and the following disclaimer.
13// * Redistributions in binary form must reproduce the above
14// copyright notice, this list of conditions and the following
15// disclaimer in the documentation and/or other materials provided
16// with the distribution.
17// * Neither the name of Novartis Institutes for BioMedical Research Inc.
18// nor the names of its contributors may be used to endorse or promote
19// products derived from this software without specific prior written
20// permission.
21//
22// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33//
34
35#include <RDGeneral/export.h>
36#ifndef RD_REACTION_H_17Aug2006
37#define RD_REACTION_H_17Aug2006
38
39#include <GraphMol/RDKitBase.h>
40#include <RDGeneral/RDProps.h>
42#include <vector>
43
44namespace RDKit {
45class ReactionPickler;
46
47//! used to indicate an error in the chemical reaction engine
49 : public std::exception {
50 public:
51 //! construct with an error message
52 explicit ChemicalReactionException(const char *msg) : _msg(msg) {}
53 //! construct with an error message
54 explicit ChemicalReactionException(const std::string msg) : _msg(msg) {}
55 //! get the error message
56 const char *what() const noexcept override { return _msg.c_str(); }
57 ~ChemicalReactionException() noexcept override = default;
58
59 private:
60 std::string _msg;
61};
62
63//! This is a class for storing and applying general chemical reactions.
64/*!
65 basic usage will be something like:
66
67 \verbatim
68 ChemicalReaction rxn;
69 rxn.addReactantTemplate(r1);
70 rxn.addReactantTemplate(r2);
71 rxn.addProductTemplate(p1);
72 rxn.initReactantMatchers();
73
74 MOL_SPTR_VECT prods;
75 for(MOL_SPTR_VECT::const_iterator r1It=reactantSet1.begin();
76 r1It!=reactantSet1.end();++r1It;){
77 for(MOL_SPTR_VECT::const_iterator r2It=reactantSet2.begin();
78 r2It!=reactantSet2.end();++r2It;){
79 MOL_SPTR_VECT rVect(2);
80 rVect[0] = *r1It;
81 rVect[1] = *r2It;
82
83 std::vector<MOL_SPTR_VECT> lprods;
84 lprods = rxn.runReactants(rVect);
85 for(std::vector<MOL_SPTR_VECT>::const_iterator lpIt=lprods.begin();
86 lpIt!=lprods.end();++lpIt){
87 // we know this is a single-product reaction:
88 prods.push_back((*lpIt)[0]);
89 }
90 }
91 }
92 \endverbatim
93
94 NOTES:
95 - to allow more control over the reaction, it is possible to flag reactant
96 atoms as being protected by setting the common_properties::_protected
97 property on those
98 atoms. Here's an example:
99 \verbatim
100 std::string smi="[O:1]>>[N:1]";
101 ChemicalReaction *rxn = RxnSmartsToChemicalReaction(smi);
102 rxn->initReactantMatchers();
103
104 MOL_SPTR_VECT reacts;
105 reacts.clear();
106 smi = "OCO";
107 ROMol *mol = SmilesToMol(smi);
108 reacts.push_back(ROMOL_SPTR(mol));
109 std::vector<MOL_SPTR_VECT> prods;
110 prods = rxn->runReactants(reacts);
111 // here prods has two entries, because there are two Os in the
112 // reactant.
113
114 reacts[0]->getAtomWithIdx(0)->setProp(common_properties::_protected,1);
115 prods = rxn->runReactants(reacts);
116 // here prods only has one entry, the reaction at atom 0
117 // has been blocked by the _protected property
118 \endverbatim
119
120*/
122 friend class ReactionPickler;
123
124 private:
125 void copy(const ChemicalReaction &other) {
126 RDProps::operator=(other);
127 df_needsInit = other.df_needsInit;
128 df_implicitProperties = other.df_implicitProperties;
129 m_reactantTemplates.clear();
130 m_reactantTemplates.reserve(other.m_reactantTemplates.size());
131 for (ROMOL_SPTR reactant_template : other.m_reactantTemplates) {
132 m_reactantTemplates.emplace_back(new RWMol(*reactant_template));
133 }
134 m_productTemplates.clear();
135 m_productTemplates.reserve(other.m_productTemplates.size());
136 for (ROMOL_SPTR product_template : other.m_productTemplates) {
137 m_productTemplates.emplace_back(new RWMol(*product_template));
138 }
139 m_agentTemplates.clear();
140 m_agentTemplates.reserve(other.m_agentTemplates.size());
141 for (ROMOL_SPTR agent_template : other.m_agentTemplates) {
142 m_agentTemplates.emplace_back(new RWMol(*agent_template));
143 }
144 d_substructParams = other.d_substructParams;
145 }
146
147 public:
149 //! construct a reaction from a pickle string
150 ChemicalReaction(const std::string &binStr);
151 ChemicalReaction(const ChemicalReaction &other) : RDProps() { copy(other); }
153 if (this != &other) {
154 copy(other);
155 }
156 return *this;
157 }
158
159 //! Adds a new reactant template
160 /*!
161 \return the number of reactants
162
163 */
164 unsigned int addReactantTemplate(ROMOL_SPTR mol) {
165 this->df_needsInit = true;
166 this->m_reactantTemplates.push_back(mol);
167 return rdcast<unsigned int>(this->m_reactantTemplates.size());
168 }
169
170 //! Adds a new agent template
171 /*!
172 \return the number of agent
173
174 */
175 unsigned int addAgentTemplate(ROMOL_SPTR mol) {
176 this->m_agentTemplates.push_back(mol);
177 return rdcast<unsigned int>(this->m_agentTemplates.size());
178 }
179
180 //! Adds a new product template
181 /*!
182 \return the number of products
183
184 */
185 unsigned int addProductTemplate(ROMOL_SPTR mol) {
186 this->m_productTemplates.push_back(mol);
187 return rdcast<unsigned int>(this->m_productTemplates.size());
188 }
189
190 //! Removes the reactant templates from a reaction if atom mapping ratio is
191 /// below a given threshold
192 /*! By default the removed reactant templates were attached to the agent
193 templates.
194 An alternative will be to provide a pointer to a molecule vector where
195 these reactants should be saved.
196 */
197 void removeUnmappedReactantTemplates(double thresholdUnmappedAtoms = 0.2,
198 bool moveToAgentTemplates = true,
199 MOL_SPTR_VECT *targetVector = nullptr);
200
201 //! Removes the product templates from a reaction if its atom mapping ratio is
202 /// below a given threshold
203 /*! By default the removed products templates were attached to the agent
204 templates.
205 An alternative will be to provide a pointer to a molecule vector where
206 these products should be saved.
207 */
208 void removeUnmappedProductTemplates(double thresholdUnmappedAtoms = 0.2,
209 bool moveToAgentTemplates = true,
210 MOL_SPTR_VECT *targetVector = nullptr);
211
212 /*! Removes the agent templates from a reaction if a pointer to a
213 molecule vector is provided the agents are stored therein.*/
214 void removeAgentTemplates(MOL_SPTR_VECT *targetVector = nullptr);
215
216 //! Runs the reaction on a set of reactants
217 /*!
218
219 \param reactants the reactants to be used. The length of this must be equal
220 to this->getNumReactantTemplates()
221 \param maxProducts: if non zero, the maximum number of products to generate
222 before stopping. If hit a warning will be generated.
223
224 \return a vector of vectors of products. Each subvector will be
225 this->getNumProductTemplates() long.
226
227 We return a vector of vectors of products because each individual template
228 may map multiple times onto its reactant. This leads to multiple possible
229 result sets.
230 */
231 std::vector<MOL_SPTR_VECT> runReactants(
232 const MOL_SPTR_VECT reactants, unsigned int numProducts = 1000) const;
233
234 //! Runs a single reactant against a single reactant template
235 /*!
236 \param reactant The single reactant to use
237
238 \param reactantTemplateIdx the reactant template to target in the reaction
239 */
240 std::vector<MOL_SPTR_VECT> runReactant(
241 ROMOL_SPTR reactant, unsigned int reactantTemplateIdx) const;
242
243 //! Runs a single reactant in place (the reactant is modified)
244 /*!
245 This is only useable with reactions which have a single reactant and product
246 and where no atoms are added in the product.
247
248 \param reactant The single reactant to use
249 \param removeUnmatchedAtoms toggles whether or not atoms from the reactant
250 which do not match template atoms are removed.
251
252 \return whether or not the reactant was actually modified
253 */
254 bool runReactant(RWMol &reactant, bool removeUnmatchedAtoms = true) const;
255
257 return this->m_reactantTemplates;
258 }
259 const MOL_SPTR_VECT &getAgents() const { return this->m_agentTemplates; }
260 const MOL_SPTR_VECT &getProducts() const { return this->m_productTemplates; }
261
262 MOL_SPTR_VECT::const_iterator beginReactantTemplates() const {
263 return this->m_reactantTemplates.begin();
264 }
265 MOL_SPTR_VECT::const_iterator endReactantTemplates() const {
266 return this->m_reactantTemplates.end();
267 }
268
269 MOL_SPTR_VECT::const_iterator beginProductTemplates() const {
270 return this->m_productTemplates.begin();
271 }
272 MOL_SPTR_VECT::const_iterator endProductTemplates() const {
273 return this->m_productTemplates.end();
274 }
275
276 MOL_SPTR_VECT::const_iterator beginAgentTemplates() const {
277 return this->m_agentTemplates.begin();
278 }
279 MOL_SPTR_VECT::const_iterator endAgentTemplates() const {
280 return this->m_agentTemplates.end();
281 }
282
283 MOL_SPTR_VECT::iterator beginReactantTemplates() {
284 return this->m_reactantTemplates.begin();
285 }
286 MOL_SPTR_VECT::iterator endReactantTemplates() {
287 return this->m_reactantTemplates.end();
288 }
289
290 MOL_SPTR_VECT::iterator beginProductTemplates() {
291 return this->m_productTemplates.begin();
292 }
293 MOL_SPTR_VECT::iterator endProductTemplates() {
294 return this->m_productTemplates.end();
295 }
296
297 MOL_SPTR_VECT::iterator beginAgentTemplates() {
298 return this->m_agentTemplates.begin();
299 }
300 MOL_SPTR_VECT::iterator endAgentTemplates() {
301 return this->m_agentTemplates.end();
302 }
303 unsigned int getNumReactantTemplates() const {
304 return rdcast<unsigned int>(this->m_reactantTemplates.size());
305 }
306 unsigned int getNumProductTemplates() const {
307 return rdcast<unsigned int>(this->m_productTemplates.size());
308 }
309 unsigned int getNumAgentTemplates() const {
310 return rdcast<unsigned int>(this->m_agentTemplates.size());
311 }
312
313 //! initializes our internal reactant-matching datastructures.
314 /*!
315 This must be called after adding reactants and before calling
316 runReactants.
317
318 \param silent: If this bool is true, no messages will be logged during the
319 validation. By default, validation problems are reported to the warning
320 and error logs depending on their severity.
321 */
322 void initReactantMatchers(bool silent = false);
323
324 bool isInitialized() const { return !df_needsInit; }
325
326 //! validates the reactants and products to make sure the reaction seems
327 /// "reasonable"
328 /*!
329 \return true if the reaction validates without errors (warnings do not
330 stop validation)
331
332 \param numWarnings used to return the number of validation warnings
333 \param numErrors used to return the number of validation errors
334
335 \param silent: If this bool is true, no messages will be logged during the
336 validation. By default, validation problems are reported to the warning
337 and error logs depending on their severity.
338
339 */
340 bool validate(unsigned int &numWarnings, unsigned int &numErrors,
341 bool silent = false) const;
342
343 //! returns whether or not the reaction uses implicit
344 //! properties on the product atoms
345 /*!
346
347 This toggles whether or not unspecified atomic properties in the
348 products are considered to be implicit and should be copied from
349 the actual reactants. This is necessary due to a semantic difference
350 between the "reaction SMARTS" approach and the MDL RXN
351 approach:
352 In "reaction SMARTS", this reaction:
353 [C:1]-[Br:2].[O-:3]>>[C:1]-[O:3].[Br-:2]
354 applied to [CH4+]Br should yield [CH4+]O
355 Something similar drawn in an rxn file, and applied to
356 [CH4+]Br should yield [CH3]O.
357 In rxn there is no charge on the product C because nothing is
358 specified in the rxn file; in "SMARTS" the charge from the
359 actual reactants is not *removed* because no charge is
360 specified in the reaction.
361
362 */
363 bool getImplicitPropertiesFlag() const { return df_implicitProperties; }
364 //! sets the implicit properties flag. See the documentation for
365 //! getImplicitProertiesFlag() for a discussion of what this means.
366 void setImplicitPropertiesFlag(bool val) { df_implicitProperties = val; }
367
369 return d_substructParams;
370 }
371 SubstructMatchParameters &getSubstructParams() { return d_substructParams; }
372
373 private:
374 bool df_needsInit{true};
375 bool df_implicitProperties{false};
376 MOL_SPTR_VECT m_reactantTemplates, m_productTemplates, m_agentTemplates;
377 SubstructMatchParameters d_substructParams;
378};
379
380//! tests whether or not the molecule has a substructure match
381//! to the reaction's reactants
382//! the \c which argument is used to return which of the reactants
383//! the molecule matches.
385 const ChemicalReaction &rxn, const ROMol &mol,
386 std::vector<unsigned int> &which, bool stopAtFirstMatch = false);
387//! \overload
389 const ChemicalReaction &rxn, const ROMol &mol, unsigned int &which);
390//! \overload
392 const ChemicalReaction &rxn, const ROMol &mol);
393
394//! tests whether or not the molecule has a substructure match
395//! to the reaction's products
396//! the \c which argument is used to return which of the products
397//! the molecule matches.
399 const ChemicalReaction &rxn, const ROMol &mol,
400 std::vector<unsigned int> &which, bool stopAtFirstMatch = false);
401//! \overload
403 const ChemicalReaction &rxn, const ROMol &mol, unsigned int &which);
404//! \overload
406 const ChemicalReaction &rxn, const ROMol &mol);
407
408//! tests whether or not the molecule has a substructure match
409//! to any of the reaction's agents
410//! the \c which argument is used to return which of the agents
411//! the molecule matches. If there's no match, it is equal to the number
412//! of agents on return
414 const ChemicalReaction &rxn, const ROMol &mol, unsigned int &which);
415//! \overload
417 const ChemicalReaction &rxn, const ROMol &mol);
418
419//! returns indices of the atoms in each reactant that are changed
420//! in the reaction
421/*!
422 \param rxn the reaction we are interested in
423
424 \param mappedAtomsOnly if set, atoms that are not mapped will not be included
425 in the list of changed atoms (otherwise they are automatically included)
426
427 How are changed atoms recognized?
428 1) Atoms whose degree changes
429 2) Atoms whose bonding pattern changes
430 3) unmapped atoms (unless the mappedAtomsOnly flag is set)
431 4) Atoms connected to unmapped atoms
432 5) Atoms whose atomic number changes (unless the
433 corresponding product atom is a dummy)
434 6) Atoms with more than one atomic number query (unless the
435 corresponding product atom is a dummy)
436
437 Note that the atomic number of a query atom depends on how it's constructed.
438 When coming from SMARTS: if the first query is an atomic label/number that
439 sets the atomic number, otherwise it's zero.
440 For example [O;$(OC)] is atomic number 8 while [$(OC);O] is atomic
441 number 0.
442 When coming from RXN: the atomic number of the atom in the rxn file sets
443 the value.
444 */
446getReactingAtoms(const ChemicalReaction &rxn, bool mappedAtomsOnly = false);
447
448//! add the recursive queries to the reactants of a reaction
449/*!
450 This does its work using RDKit::addRecursiveQueries()
451
452 \param rxn the reaction we are interested in
453 \param queries - the dictionary of named queries to add
454 \param propName - the atom property to use to get query names
455 optional:
456 \param reactantLabels - to store pairs of (atom index, query string)
457 per reactant
458
459 NOTES:
460 - existing query information, if present, will be supplemented (AND logic)
461 - non-query atoms will be replaced with query atoms using only the query
462 logic
463 - query names can be present as comma separated lists, they will then
464 be combined using OR logic.
465 - throws a KeyErrorException if a particular query name is not present
466 in \c queries
467
468 */
470 ChemicalReaction &rxn, const std::map<std::string, ROMOL_SPTR> &queries,
471 const std::string &propName,
472 std::vector<std::vector<std::pair<unsigned int, std::string>>>
473 *reactantLabels = nullptr);
474
475} // namespace RDKit
476
477namespace RDDepict {
478//! \brief Generate 2D coordinates (a depiction) for a reaction
479/*!
480
481 \param rxn the reaction we are interested in
482
483 \param spacing the spacing between components of the reaction
484
485 \param updateProps if set, properties such as conjugation and
486 hybridization will be calculated for the reactant and product
487 templates before generating coordinates. This should result in
488 better depictions, but can lead to errors in some cases.
489
490 \param canonOrient canonicalize the orientation so that the long
491 axes align with the x-axis etc.
492
493 \param nFlipsPerSample - the number of rotatable bonds that are
494 flipped at random for each sample
495
496 \param nSamples - the number of samples
497
498 \param sampleSeed - seed for the random sampling process
499
500 \param permuteDeg4Nodes - try permuting the drawing order of bonds around
501 atoms with four neighbors in order to improve the depiction
502
503 for the other parameters see the documentation for compute2DCoords()
504
505*/
506RDKIT_CHEMREACTIONS_EXPORT void compute2DCoordsForReaction(
507 RDKit::ChemicalReaction &rxn, double spacing = 1.0, bool updateProps = true,
508 bool canonOrient = false, unsigned int nFlipsPerSample = 0,
509 unsigned int nSamples = 0, int sampleSeed = 0,
510 bool permuteDeg4Nodes = false);
511
512} // namespace RDDepict
513
514#endif
pulls in the core RDKit functionality
used to indicate an error in the chemical reaction engine
Definition Reaction.h:49
const char * what() const noexcept override
get the error message
Definition Reaction.h:56
ChemicalReactionException(const char *msg)
construct with an error message
Definition Reaction.h:52
ChemicalReactionException(const std::string msg)
construct with an error message
Definition Reaction.h:54
~ChemicalReactionException() noexcept override=default
This is a class for storing and applying general chemical reactions.
Definition Reaction.h:121
unsigned int addProductTemplate(ROMOL_SPTR mol)
Adds a new product template.
Definition Reaction.h:185
SubstructMatchParameters & getSubstructParams()
Definition Reaction.h:371
unsigned int addAgentTemplate(ROMOL_SPTR mol)
Adds a new agent template.
Definition Reaction.h:175
unsigned int addReactantTemplate(ROMOL_SPTR mol)
Adds a new reactant template.
Definition Reaction.h:164
unsigned int getNumAgentTemplates() const
Definition Reaction.h:309
const SubstructMatchParameters & getSubstructParams() const
Definition Reaction.h:368
bool getImplicitPropertiesFlag() const
Definition Reaction.h:363
unsigned int getNumReactantTemplates() const
Definition Reaction.h:303
ChemicalReaction & operator=(const ChemicalReaction &other)
Definition Reaction.h:152
ChemicalReaction(const std::string &binStr)
construct a reaction from a pickle string
MOL_SPTR_VECT::iterator beginProductTemplates()
Definition Reaction.h:290
void removeUnmappedReactantTemplates(double thresholdUnmappedAtoms=0.2, bool moveToAgentTemplates=true, MOL_SPTR_VECT *targetVector=nullptr)
MOL_SPTR_VECT::const_iterator beginProductTemplates() const
Definition Reaction.h:269
void initReactantMatchers(bool silent=false)
initializes our internal reactant-matching datastructures.
std::vector< MOL_SPTR_VECT > runReactants(const MOL_SPTR_VECT reactants, unsigned int numProducts=1000) const
Runs the reaction on a set of reactants.
const MOL_SPTR_VECT & getReactants() const
Definition Reaction.h:256
MOL_SPTR_VECT::const_iterator endReactantTemplates() const
Definition Reaction.h:265
void setImplicitPropertiesFlag(bool val)
Definition Reaction.h:366
const MOL_SPTR_VECT & getAgents() const
Definition Reaction.h:259
MOL_SPTR_VECT::iterator endProductTemplates()
Definition Reaction.h:293
unsigned int getNumProductTemplates() const
Definition Reaction.h:306
MOL_SPTR_VECT::const_iterator endProductTemplates() const
Definition Reaction.h:272
bool isInitialized() const
Definition Reaction.h:324
ChemicalReaction(const ChemicalReaction &other)
Definition Reaction.h:151
MOL_SPTR_VECT::const_iterator beginAgentTemplates() const
Definition Reaction.h:276
void removeAgentTemplates(MOL_SPTR_VECT *targetVector=nullptr)
std::vector< MOL_SPTR_VECT > runReactant(ROMOL_SPTR reactant, unsigned int reactantTemplateIdx) const
Runs a single reactant against a single reactant template.
MOL_SPTR_VECT::const_iterator beginReactantTemplates() const
Definition Reaction.h:262
const MOL_SPTR_VECT & getProducts() const
Definition Reaction.h:260
bool runReactant(RWMol &reactant, bool removeUnmatchedAtoms=true) const
Runs a single reactant in place (the reactant is modified)
MOL_SPTR_VECT::iterator beginReactantTemplates()
Definition Reaction.h:283
MOL_SPTR_VECT::iterator endAgentTemplates()
Definition Reaction.h:300
MOL_SPTR_VECT::iterator beginAgentTemplates()
Definition Reaction.h:297
MOL_SPTR_VECT::iterator endReactantTemplates()
Definition Reaction.h:286
void removeUnmappedProductTemplates(double thresholdUnmappedAtoms=0.2, bool moveToAgentTemplates=true, MOL_SPTR_VECT *targetVector=nullptr)
MOL_SPTR_VECT::const_iterator endAgentTemplates() const
Definition Reaction.h:279
bool validate(unsigned int &numWarnings, unsigned int &numErrors, bool silent=false) const
RWMol is a molecule class that is intended to be edited.
Definition RWMol.h:32
handles pickling (serializing) reactions
#define RDKIT_CHEMREACTIONS_EXPORT
Definition export.h:49
Std stuff.
std::vector< INT_VECT > VECT_INT_VECT
Definition types.h:303
RDKIT_CHEMREACTIONS_EXPORT bool isMoleculeAgentOfReaction(const ChemicalReaction &rxn, const ROMol &mol, unsigned int &which)
RDKIT_CHEMREACTIONS_EXPORT bool isMoleculeReactantOfReaction(const ChemicalReaction &rxn, const ROMol &mol, std::vector< unsigned int > &which, bool stopAtFirstMatch=false)
RDKIT_CHEMREACTIONS_EXPORT VECT_INT_VECT getReactingAtoms(const ChemicalReaction &rxn, bool mappedAtomsOnly=false)
RDKIT_CHEMREACTIONS_EXPORT bool isMoleculeProductOfReaction(const ChemicalReaction &rxn, const ROMol &mol, std::vector< unsigned int > &which, bool stopAtFirstMatch=false)
boost::shared_ptr< ROMol > ROMOL_SPTR
std::vector< boost::shared_ptr< ROMol > > MOL_SPTR_VECT
RDKIT_CHEMREACTIONS_EXPORT void addRecursiveQueriesToReaction(ChemicalReaction &rxn, const std::map< std::string, ROMOL_SPTR > &queries, const std::string &propName, std::vector< std::vector< std::pair< unsigned int, std::string > > > *reactantLabels=nullptr)
add the recursive queries to the reactants of a reaction