1 // $Id$
2 //
3 //  Copyright (c) 2007, Novartis Institutes for BioMedical Research Inc.
4 //  All rights reserved.
5 //
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are
8 // met:
9 //
10 //     * Redistributions of source code must retain the above copyright
11 //       notice, this list of conditions and the following disclaimer.
12 //     * Redistributions in binary form must reproduce the above
13 //       copyright notice, this list of conditions and the following
14 //       disclaimer in the documentation and/or other materials provided
15 //       with the distribution.
16 //     * Neither the name of Novartis Institutes for BioMedical Research Inc.
17 //       nor the names of its contributors may be used to endorse or promote
18 //       products derived from this software without specific prior written
19 //       permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 //
33 #include <RDGeneral/test.h>
34 #include <RDGeneral/RDLog.h>
35 #include <RDGeneral/utils.h>
36 #include <GraphMol/RDKitBase.h>
37 #include <string>
38 #include <iostream>
39 #include <GraphMol/ChemReactions/Reaction.h>
40 #include <GraphMol/ChemReactions/ReactionParser.h>
41 #include "GraphMol/ChemReactions/ReactionFingerprints.h"
42 #include <DataStructs/BitOps.h>
43 #include <GraphMol/ChemReactions/ReactionUtils.h>
44 #include <GraphMol/Fingerprints/AtomPairs.h>
45 
46 using namespace RDKit;
47 
testStructuralFingerprintsReaction()48 void testStructuralFingerprintsReaction() {
49   BOOST_LOG(rdErrorLog) << "-------------------------------------" << std::endl;
50   BOOST_LOG(rdErrorLog) << "    Test Reaction StructuralFingerprint"
51                         << std::endl;
52   {
53     std::string reaction, reactionq;
54     ChemicalReaction *rxn, *rxnq;
55 
56     reaction = "C1CCCCC1>>C1CCNCC1";
57     reactionq = "C1CCCCC1>>C1CCNCC1";
58 
59     rxn = RxnSmartsToChemicalReaction(reaction, nullptr, true);
60     rxnq = RxnSmartsToChemicalReaction(reactionq, nullptr, true);
61     TEST_ASSERT(rxn);
62     TEST_ASSERT(rxnq);
63     ReactionFingerprintParams params;
64     params.fpType = PatternFP;
65     params.fpSize = 4096;
66 
67     ExplicitBitVect *rxnFP = StructuralFingerprintChemReaction(*rxn, params);
68     ExplicitBitVect *rxnqFP = StructuralFingerprintChemReaction(*rxnq, params);
69     TEST_ASSERT(AllProbeBitsMatch(*rxnqFP, *rxnFP));
70 
71     TEST_ASSERT(rxn->getNumReactantTemplates() == 1);
72     TEST_ASSERT(rxn->getNumProductTemplates() == 1);
73     TEST_ASSERT(rxnq->getNumReactantTemplates() == 1);
74     TEST_ASSERT(rxnq->getNumProductTemplates() == 1);
75 
76     MOL_SPTR_VECT::const_iterator reacts_iter = rxn->beginReactantTemplates();
77     MOL_SPTR_VECT::const_iterator reacts_iterq = rxnq->beginReactantTemplates();
78     MOL_SPTR_VECT::const_iterator products_iter = rxn->beginProductTemplates();
79     MOL_SPTR_VECT::const_iterator products_iterq =
80         rxnq->beginProductTemplates();
81 
82     MatchVectType mv;
83     TEST_ASSERT(SubstructMatch(*reacts_iter->get(), *reacts_iterq->get(), mv))
84     TEST_ASSERT(
85         SubstructMatch(*products_iter->get(), *products_iterq->get(), mv))
86 
87     delete rxn;
88     delete rxnq;
89     delete rxnFP;
90     delete rxnqFP;
91   }
92   {
93     std::string reaction, reactionq;
94     ChemicalReaction *rxn, *rxnq;
95 
96     reaction = "C1CCCCC1>>C1CCNCC1";
97     reactionq = "C1CCCCC1>>C1CCOCC1";
98 
99     rxn = RxnSmartsToChemicalReaction(reaction, nullptr, true);
100     rxnq = RxnSmartsToChemicalReaction(reactionq, nullptr, true);
101     TEST_ASSERT(rxn);
102     TEST_ASSERT(rxnq);
103 
104     ReactionFingerprintParams params;
105     params.fpType = PatternFP;
106     params.fpSize = 4096;
107 
108     ExplicitBitVect *rxnFP = StructuralFingerprintChemReaction(*rxn, params);
109     ExplicitBitVect *rxnqFP = StructuralFingerprintChemReaction(*rxnq, params);
110 
111     TEST_ASSERT(!AllProbeBitsMatch(*rxnqFP, *rxnFP));
112 
113     TEST_ASSERT(rxn->getNumReactantTemplates() == 1);
114     TEST_ASSERT(rxn->getNumProductTemplates() == 1);
115     TEST_ASSERT(rxnq->getNumReactantTemplates() == 1);
116     TEST_ASSERT(rxnq->getNumProductTemplates() == 1);
117 
118     MOL_SPTR_VECT::const_iterator reacts_iter = rxn->beginReactantTemplates();
119     MOL_SPTR_VECT::const_iterator reacts_iterq = rxnq->beginReactantTemplates();
120     MOL_SPTR_VECT::const_iterator products_iter = rxn->beginProductTemplates();
121     MOL_SPTR_VECT::const_iterator products_iterq =
122         rxnq->beginProductTemplates();
123 
124     MatchVectType mv;
125     TEST_ASSERT(SubstructMatch(*reacts_iter->get(), *reacts_iterq->get(), mv))
126     TEST_ASSERT(
127         !SubstructMatch(*products_iter->get(), *products_iterq->get(), mv))
128 
129     delete rxn;
130     delete rxnq;
131     delete rxnFP;
132     delete rxnqFP;
133   }
134   {
135     std::string reaction, reactionq, reactionq2;
136     ChemicalReaction *rxn, *rxnq, *rxnq2;
137 
138     reaction = "C1CCCCC1>>C1CCNCC1";
139     reactionq = ">>C1CCNCC1";
140     reactionq2 = ">>C1CCOCC1";
141 
142     rxn = RxnSmartsToChemicalReaction(reaction, nullptr, true);
143     rxnq = RxnSmartsToChemicalReaction(reactionq, nullptr, true);
144     rxnq2 = RxnSmartsToChemicalReaction(reactionq2, nullptr, true);
145     TEST_ASSERT(rxn);
146     TEST_ASSERT(rxnq);
147     TEST_ASSERT(rxnq2);
148 
149     ReactionFingerprintParams params;
150     params.fpType = PatternFP;
151     params.fpSize = 4096;
152     ExplicitBitVect *rxnFP = StructuralFingerprintChemReaction(*rxn, params);
153     ExplicitBitVect *rxnqFP = StructuralFingerprintChemReaction(*rxnq, params);
154     ExplicitBitVect *rxnq2FP =
155         StructuralFingerprintChemReaction(*rxnq2, params);
156 
157     TEST_ASSERT(AllProbeBitsMatch(*rxnqFP, *rxnFP));
158     TEST_ASSERT(!AllProbeBitsMatch(*rxnq2FP, *rxnFP));
159 
160     TEST_ASSERT(rxn->getNumReactantTemplates() == 1);
161     TEST_ASSERT(rxn->getNumProductTemplates() == 1);
162     TEST_ASSERT(rxnq->getNumReactantTemplates() == 0);
163     TEST_ASSERT(rxnq->getNumProductTemplates() == 1);
164     TEST_ASSERT(rxnq2->getNumReactantTemplates() == 0);
165     TEST_ASSERT(rxnq2->getNumProductTemplates() == 1);
166 
167     MOL_SPTR_VECT::const_iterator products_iter = rxn->beginProductTemplates();
168     MOL_SPTR_VECT::const_iterator products_iterq =
169         rxnq->beginProductTemplates();
170     MOL_SPTR_VECT::const_iterator products_iterq2 =
171         rxnq2->beginProductTemplates();
172 
173     MatchVectType mv;
174     TEST_ASSERT(
175         SubstructMatch(*products_iter->get(), *products_iterq->get(), mv))
176     TEST_ASSERT(
177         !SubstructMatch(*products_iter->get(), *products_iterq2->get(), mv))
178 
179     delete rxn;
180     delete rxnq;
181     delete rxnq2;
182     delete rxnFP;
183     delete rxnqFP;
184     delete rxnq2FP;
185   }
186   {
187     std::string reaction, reactionq, reactionq2;
188     ChemicalReaction *rxn, *rxnq, *rxnq2;
189 
190     reaction = "C1CCCCC1>>C1CCNCC1";
191     reactionq = "C1CCCCC1>>";
192     reactionq2 = "C1CCOCC1>>";
193 
194     rxn = RxnSmartsToChemicalReaction(reaction, nullptr, true);
195     rxnq = RxnSmartsToChemicalReaction(reactionq, nullptr, true);
196     rxnq2 = RxnSmartsToChemicalReaction(reactionq2, nullptr, true);
197     TEST_ASSERT(rxn);
198     TEST_ASSERT(rxnq);
199     TEST_ASSERT(rxnq2);
200 
201     ReactionFingerprintParams params;
202     params.fpType = PatternFP;
203     params.fpSize = 4096;
204 
205     ExplicitBitVect *rxnFP = StructuralFingerprintChemReaction(*rxn, params);
206     ExplicitBitVect *rxnqFP = StructuralFingerprintChemReaction(*rxnq, params);
207     ExplicitBitVect *rxnq2FP =
208         StructuralFingerprintChemReaction(*rxnq2, params);
209 
210     TEST_ASSERT(AllProbeBitsMatch(*rxnqFP, *rxnFP));
211     TEST_ASSERT(!AllProbeBitsMatch(*rxnq2FP, *rxnFP));
212 
213     TEST_ASSERT(rxn->getNumReactantTemplates() == 1);
214     TEST_ASSERT(rxn->getNumProductTemplates() == 1);
215     TEST_ASSERT(rxnq->getNumReactantTemplates() == 1);
216     TEST_ASSERT(rxnq->getNumProductTemplates() == 0);
217     TEST_ASSERT(rxnq2->getNumReactantTemplates() == 1);
218     TEST_ASSERT(rxnq2->getNumProductTemplates() == 0);
219 
220     MOL_SPTR_VECT::const_iterator react_iter = rxn->beginReactantTemplates();
221     MOL_SPTR_VECT::const_iterator react_iterq = rxnq->beginReactantTemplates();
222     MOL_SPTR_VECT::const_iterator react_iterq2 =
223         rxnq2->beginReactantTemplates();
224 
225     MatchVectType mv;
226     TEST_ASSERT(SubstructMatch(*react_iter->get(), *react_iterq->get(), mv))
227     TEST_ASSERT(!SubstructMatch(*react_iter->get(), *react_iterq2->get(), mv))
228 
229     delete rxn;
230     delete rxnq;
231     delete rxnq2;
232     delete rxnFP;
233     delete rxnqFP;
234     delete rxnq2FP;
235   }
236   {
237     std::string reaction, reactionq, reactionq2;
238     ChemicalReaction *rxn, *rxnq, *rxnq2;
239 
240     reaction = "C1CCCCC1>>C1CCNCC1";
241     reactionq = "CCC>>CNC";
242     reactionq2 = "CCCCC>>CCCCN";
243 
244     rxn = RxnSmartsToChemicalReaction(reaction, nullptr, true);
245     rxnq = RxnSmartsToChemicalReaction(reactionq, nullptr, true);
246     rxnq2 = RxnSmartsToChemicalReaction(reactionq2, nullptr, true);
247     TEST_ASSERT(rxn);
248     TEST_ASSERT(rxnq);
249     TEST_ASSERT(rxnq2);
250 
251     ReactionFingerprintParams params;
252     params.fpType = PatternFP;
253     params.fpSize = 4096;
254 
255     ExplicitBitVect *rxnFP = StructuralFingerprintChemReaction(*rxn, params);
256     ExplicitBitVect *rxnqFP = StructuralFingerprintChemReaction(*rxnq, params);
257     ExplicitBitVect *rxnq2FP =
258         StructuralFingerprintChemReaction(*rxnq2, params);
259 
260     TEST_ASSERT(AllProbeBitsMatch(*rxnqFP, *rxnFP));
261     TEST_ASSERT(AllProbeBitsMatch(*rxnq2FP, *rxnFP));
262 
263     TEST_ASSERT(rxn->getNumReactantTemplates() == 1);
264     TEST_ASSERT(rxn->getNumProductTemplates() == 1);
265     TEST_ASSERT(rxnq->getNumReactantTemplates() == 1);
266     TEST_ASSERT(rxnq->getNumProductTemplates() == 1);
267     TEST_ASSERT(rxnq2->getNumReactantTemplates() == 1);
268     TEST_ASSERT(rxnq2->getNumProductTemplates() == 1);
269 
270     MOL_SPTR_VECT::const_iterator react_iter = rxn->beginReactantTemplates();
271     MOL_SPTR_VECT::const_iterator react_iterq = rxnq->beginReactantTemplates();
272     MOL_SPTR_VECT::const_iterator react_iterq2 =
273         rxnq2->beginReactantTemplates();
274     MOL_SPTR_VECT::const_iterator products_iter = rxn->beginProductTemplates();
275     MOL_SPTR_VECT::const_iterator products_iterq =
276         rxnq->beginProductTemplates();
277     MOL_SPTR_VECT::const_iterator products_iterq2 =
278         rxnq2->beginProductTemplates();
279 
280     MatchVectType mv;
281     TEST_ASSERT(SubstructMatch(*react_iter->get(), *react_iterq->get(), mv))
282     TEST_ASSERT(SubstructMatch(*react_iter->get(), *react_iterq2->get(), mv))
283     TEST_ASSERT(
284         SubstructMatch(*products_iter->get(), *products_iterq->get(), mv))
285     TEST_ASSERT(
286         SubstructMatch(*products_iter->get(), *products_iterq2->get(), mv))
287 
288     delete rxn;
289     delete rxnq;
290     delete rxnq2;
291     delete rxnFP;
292     delete rxnqFP;
293     delete rxnq2FP;
294   }
295   {
296     std::string reaction, reactionq, reactionq2;
297     ChemicalReaction *rxn, *rxnq, *rxnq2;
298     reaction = "C1CCCCC1>>C1CCNCC1";
299     reactionq = "CCC>>CNC";
300     reactionq2 = "CCCCC>>CCCCN";
301 
302     rxn = RxnSmartsToChemicalReaction(reaction, nullptr, true);
303     rxnq = RxnSmartsToChemicalReaction(reactionq, nullptr, true);
304     rxnq2 = RxnSmartsToChemicalReaction(reactionq2, nullptr, true);
305     TEST_ASSERT(rxn);
306     TEST_ASSERT(rxnq);
307     TEST_ASSERT(rxnq2);
308 
309     ReactionFingerprintParams params;
310     params.fpType = PatternFP;
311     params.fpSize = 4096;
312 
313     ExplicitBitVect *rxnFP = StructuralFingerprintChemReaction(*rxn, params);
314     ExplicitBitVect *rxnqFP = StructuralFingerprintChemReaction(*rxnq, params);
315     ExplicitBitVect *rxnq2FP =
316         StructuralFingerprintChemReaction(*rxnq2, params);
317 
318     TEST_ASSERT(AllProbeBitsMatch(*rxnqFP, *rxnFP));
319     TEST_ASSERT(AllProbeBitsMatch(*rxnq2FP, *rxnFP));
320 
321     TEST_ASSERT(hasReactionSubstructMatch(*rxn, *rxnq));
322     TEST_ASSERT(hasReactionSubstructMatch(*rxn, *rxnq2));
323 
324     delete rxn;
325     delete rxnq;
326     delete rxnq2;
327     delete rxnFP;
328     delete rxnqFP;
329     delete rxnq2FP;
330   }
331   {
332     std::string reaction, reactionq, reactionq2;
333     ChemicalReaction *rxn, *rxnq, *rxnq2;
334 
335     reaction = "C1CCCCC1>>C1CCNCC1";
336     reactionq = "C1CCCCC1>>C1CCNCC1";
337     reactionq2 = "C1CCCCC1>>C1CCOCC1";
338 
339     rxn = RxnSmartsToChemicalReaction(reaction, nullptr, true);
340     rxnq = RxnSmartsToChemicalReaction(reactionq, nullptr, true);
341     rxnq2 = RxnSmartsToChemicalReaction(reactionq2, nullptr, true);
342     TEST_ASSERT(rxn);
343     TEST_ASSERT(rxnq);
344     TEST_ASSERT(rxnq2);
345 
346     ReactionFingerprintParams params;
347     params.fpType = MorganFP;
348     params.fpSize = 4096;
349 
350     ExplicitBitVect *rxnFP = StructuralFingerprintChemReaction(*rxn, params);
351     ExplicitBitVect *rxnqFP = StructuralFingerprintChemReaction(*rxnq, params);
352     ExplicitBitVect *rxnq2FP =
353         StructuralFingerprintChemReaction(*rxnq2, params);
354 
355     TEST_ASSERT(AllProbeBitsMatch(*rxnqFP, *rxnFP));
356     TEST_ASSERT(!AllProbeBitsMatch(*rxnq2FP, *rxnFP));
357 
358     delete rxn;
359     delete rxnq;
360     delete rxnq2;
361     delete rxnFP;
362     delete rxnqFP;
363     delete rxnq2FP;
364   }
365   {
366     std::string reaction, reactionq, reactionq2;
367     ChemicalReaction *rxn, *rxnq, *rxnq2;
368 
369     reaction = "C1CCCCC1>>C1CCNCC1";
370     reactionq = "C1CCCCC1>>C1CCNCC1";
371     reactionq2 = "C1CCCCC1>>C1CCOCC1";
372 
373     rxn = RxnSmartsToChemicalReaction(reaction, nullptr, true);
374     rxnq = RxnSmartsToChemicalReaction(reactionq, nullptr, true);
375     rxnq2 = RxnSmartsToChemicalReaction(reactionq2, nullptr, true);
376     TEST_ASSERT(rxn);
377     TEST_ASSERT(rxnq);
378     TEST_ASSERT(rxnq2);
379 
380     ReactionFingerprintParams params;
381     params.fpSize = 4096;
382 
383     ExplicitBitVect *rxnFP = StructuralFingerprintChemReaction(*rxn, params);
384     ExplicitBitVect *rxnqFP = StructuralFingerprintChemReaction(*rxnq, params);
385     ExplicitBitVect *rxnq2FP =
386         StructuralFingerprintChemReaction(*rxnq2, params);
387 
388     TEST_ASSERT(AllProbeBitsMatch(*rxnqFP, *rxnFP));
389     TEST_ASSERT(!AllProbeBitsMatch(*rxnq2FP, *rxnFP));
390 
391     delete rxn;
392     delete rxnq;
393     delete rxnq2;
394     delete rxnFP;
395     delete rxnqFP;
396     delete rxnq2FP;
397   }
398   {
399     std::string reaction, reactionq, reactionq2;
400     ChemicalReaction *rxn, *rxnq, *rxnq2;
401 
402     reaction = "C1CCCCC1>>C1CCNCC1";
403     reactionq = "C1CCCCC1>>C1CCNCC1";
404     reactionq2 = "C1CCCCC1>>C1CCOCC1";
405 
406     rxn = RxnSmartsToChemicalReaction(reaction, nullptr, true);
407     rxnq = RxnSmartsToChemicalReaction(reactionq, nullptr, true);
408     rxnq2 = RxnSmartsToChemicalReaction(reactionq2, nullptr, true);
409     TEST_ASSERT(rxn);
410     TEST_ASSERT(rxnq);
411     TEST_ASSERT(rxnq2);
412 
413     ReactionFingerprintParams params;
414     params.fpType = TopologicalTorsion;
415     params.fpSize = 4096;
416 
417     ExplicitBitVect *rxnFP = StructuralFingerprintChemReaction(*rxn, params);
418     ExplicitBitVect *rxnqFP = StructuralFingerprintChemReaction(*rxnq, params);
419     ExplicitBitVect *rxnq2FP =
420         StructuralFingerprintChemReaction(*rxnq2, params);
421 
422     TEST_ASSERT(AllProbeBitsMatch(*rxnqFP, *rxnFP));
423     TEST_ASSERT(!AllProbeBitsMatch(*rxnq2FP, *rxnFP));
424 
425     delete rxn;
426     delete rxnq;
427     delete rxnq2;
428     delete rxnFP;
429     delete rxnqFP;
430     delete rxnq2FP;
431   }
432   {
433     std::string reaction, reactionq, reactionq2;
434     ChemicalReaction *rxn, *rxnq, *rxnq2;
435 
436     reaction = "C1CCCCC1>>C1CCNCC1";
437     reactionq = "C1CCCCC1>>C1CCNCC1";
438     reactionq2 = "C1CCCCC1>>C1CCOCC1";
439 
440     rxn = RxnSmartsToChemicalReaction(reaction, nullptr, true);
441     rxnq = RxnSmartsToChemicalReaction(reactionq, nullptr, true);
442     rxnq2 = RxnSmartsToChemicalReaction(reactionq2, nullptr, true);
443     TEST_ASSERT(rxn);
444     TEST_ASSERT(rxnq);
445     TEST_ASSERT(rxnq2);
446 
447     ReactionFingerprintParams params;
448     params.fpType = RDKitFP;
449     params.fpSize = 4096;
450 
451     ExplicitBitVect *rxnFP = StructuralFingerprintChemReaction(*rxn, params);
452     ExplicitBitVect *rxnqFP = StructuralFingerprintChemReaction(*rxnq, params);
453     ExplicitBitVect *rxnq2FP =
454         StructuralFingerprintChemReaction(*rxnq2, params);
455 
456     TEST_ASSERT(AllProbeBitsMatch(*rxnqFP, *rxnFP));
457     TEST_ASSERT(!AllProbeBitsMatch(*rxnq2FP, *rxnFP));
458 
459     delete rxn;
460     delete rxnq;
461     delete rxnq2;
462     delete rxnFP;
463     delete rxnqFP;
464     delete rxnq2FP;
465   }
466   {
467     std::string reaction, reactionq, reactionq2;
468     ChemicalReaction *rxn, *rxnq, *rxnq2;
469 
470     reaction = "C1CCCCC1>>C1CCNCC1";
471     reactionq = "C1CCCCC1>>C1CCNCC1";
472     reactionq2 = "C1CCCCC1>>C1CCOCC1";
473 
474     rxn = RxnSmartsToChemicalReaction(reaction, nullptr, true);
475     rxnq = RxnSmartsToChemicalReaction(reactionq, nullptr, true);
476     rxnq2 = RxnSmartsToChemicalReaction(reactionq2, nullptr, true);
477     TEST_ASSERT(rxn);
478     TEST_ASSERT(rxnq);
479     TEST_ASSERT(rxnq2);
480 
481     ReactionFingerprintParams params;
482     params.fpType = RDKitFP;
483     params.fpSize = 4096;
484 
485     ExplicitBitVect *rxnFP = StructuralFingerprintChemReaction(*rxn, params);
486     ExplicitBitVect *rxnqFP = StructuralFingerprintChemReaction(*rxnq, params);
487     ExplicitBitVect *rxnq2FP =
488         StructuralFingerprintChemReaction(*rxnq2, params);
489 
490     TEST_ASSERT(AllProbeBitsMatch(*rxnqFP, *rxnFP));
491     TEST_ASSERT(!AllProbeBitsMatch(*rxnq2FP, *rxnFP));
492 
493     delete rxn;
494     delete rxnq;
495     delete rxnq2;
496     delete rxnFP;
497     delete rxnqFP;
498     delete rxnq2FP;
499   }
500   {
501     std::string reaction, reactionq, reactionq2;
502     ChemicalReaction *rxn, *rxnq, *rxnq2;
503 
504     reaction = "C1CCCCC1>C(=O)O.[Na]>C1CCNCC1";
505     reactionq = "C1CCCCC1>C(=O)O.[Na]>C1CCNCC1";
506     reactionq2 = "C1CCCCC1>>C1CCNCC1";
507 
508     rxn = RxnSmartsToChemicalReaction(reaction, nullptr, true);
509     rxnq = RxnSmartsToChemicalReaction(reactionq, nullptr, true);
510     rxnq2 = RxnSmartsToChemicalReaction(reactionq2, nullptr, true);
511     TEST_ASSERT(rxn);
512     TEST_ASSERT(rxnq);
513     TEST_ASSERT(rxnq2);
514 
515     ExplicitBitVect *rxnFP =
516         StructuralFingerprintChemReaction(*rxn, DefaultStructuralFPParams);
517     ExplicitBitVect *rxnqFP =
518         StructuralFingerprintChemReaction(*rxnq, DefaultStructuralFPParams);
519     ExplicitBitVect *rxnq2FP =
520         StructuralFingerprintChemReaction(*rxnq2, DefaultStructuralFPParams);
521 
522     TEST_ASSERT(AllProbeBitsMatch(*rxnqFP, *rxnFP));
523     TEST_ASSERT(AllProbeBitsMatch(*rxnq2FP, *rxnFP));
524 
525     delete rxn;
526     delete rxnq;
527     delete rxnq2;
528     delete rxnFP;
529     delete rxnqFP;
530     delete rxnq2FP;
531   }
532   {
533     std::string reaction, reactionq, reactionq2;
534     ChemicalReaction *rxn, *rxnq, *rxnq2;
535 
536     reaction = "C1CCCCC1>[Na]>C1CCNCC1";
537     reactionq = "C1CCCCC1>C(=O)O.[Na]>C1CCNCC1";
538     reactionq2 = "C1CCCCC1>>C1CCNCC1";
539 
540     rxn = RxnSmartsToChemicalReaction(reaction, nullptr, true);
541     rxnq = RxnSmartsToChemicalReaction(reactionq, nullptr, true);
542     rxnq2 = RxnSmartsToChemicalReaction(reactionq2, nullptr, true);
543     TEST_ASSERT(rxn);
544     TEST_ASSERT(rxnq);
545     TEST_ASSERT(rxnq2);
546 
547     ExplicitBitVect *rxnFP =
548         StructuralFingerprintChemReaction(*rxn, DefaultStructuralFPParams);
549     ExplicitBitVect *rxnqFP =
550         StructuralFingerprintChemReaction(*rxnq, DefaultStructuralFPParams);
551     ExplicitBitVect *rxnq2FP =
552         StructuralFingerprintChemReaction(*rxnq2, DefaultStructuralFPParams);
553 
554     TEST_ASSERT(!AllProbeBitsMatch(*rxnqFP, *rxnFP));
555     TEST_ASSERT(AllProbeBitsMatch(*rxnq2FP, *rxnFP));
556 
557     delete rxn;
558     delete rxnq;
559     delete rxnq2;
560     delete rxnFP;
561     delete rxnqFP;
562     delete rxnq2FP;
563   }
564 }
565 
testDifferenceFingerprintsReaction()566 void testDifferenceFingerprintsReaction() {
567   BOOST_LOG(rdErrorLog) << "-------------------------------------" << std::endl;
568   BOOST_LOG(rdErrorLog) << "    Test Reaction DifferenceFingerprint"
569                         << std::endl;
570   {
571     std::string reaction1, reaction2;
572     ChemicalReaction *rxn1, *rxn2;
573 
574     reaction1 = "C1CCCCC1>>C1CCCCC1";
575     reaction2 = "C1CCCCC1>>C1CCNCC1";
576 
577     rxn1 = RxnSmartsToChemicalReaction(reaction1, nullptr, true);
578     rxn2 = RxnSmartsToChemicalReaction(reaction2, nullptr, true);
579     TEST_ASSERT(rxn1);
580     TEST_ASSERT(rxn2);
581 
582     SparseIntVect<std::uint32_t> *rxn1FP =
583         DifferenceFingerprintChemReaction(*rxn1);
584     SparseIntVect<std::uint32_t> *rxn2FP =
585         DifferenceFingerprintChemReaction(*rxn2);
586 
587     TEST_ASSERT(TanimotoSimilarity(*rxn1FP, *rxn2FP) == 0.0);
588     ;
589 
590     delete rxn1;
591     delete rxn2;
592     delete rxn1FP;
593     delete rxn2FP;
594   }
595   {
596     std::string reaction1, reaction2;
597     ChemicalReaction *rxn1, *rxn2;
598 
599     reaction1 = "C1CCCCC1>>C1CCOCC1";
600     reaction2 = "C1CCCCC1>>C1CCNCC1";
601 
602     rxn1 = RxnSmartsToChemicalReaction(reaction1, nullptr, true);
603     rxn2 = RxnSmartsToChemicalReaction(reaction2, nullptr, true);
604     TEST_ASSERT(rxn1);
605     TEST_ASSERT(rxn2);
606 
607     SparseIntVect<std::uint32_t> *rxn1FP =
608         DifferenceFingerprintChemReaction(*rxn1);
609     SparseIntVect<std::uint32_t> *rxn2FP =
610         DifferenceFingerprintChemReaction(*rxn2);
611 
612     TEST_ASSERT(TanimotoSimilarity(*rxn1FP, *rxn2FP) > 0.0);
613     TEST_ASSERT(TanimotoSimilarity(*rxn1FP, *rxn2FP) <= 1.0);
614 
615     delete rxn1;
616     delete rxn2;
617     delete rxn1FP;
618     delete rxn2FP;
619   }
620   {
621     std::string reaction1, reaction2;
622     ChemicalReaction *rxn1, *rxn2;
623 
624     reaction1 = "c1ccccc1>>c1ccncn1";
625     reaction2 = "c1ccccc1>>c1ccncc1";
626     rxn1 = RxnSmartsToChemicalReaction(reaction1, nullptr, true);
627     rxn2 = RxnSmartsToChemicalReaction(reaction2, nullptr, true);
628     TEST_ASSERT(rxn1);
629     TEST_ASSERT(rxn2);
630 
631     SparseIntVect<std::uint32_t> *rxn1FP =
632         DifferenceFingerprintChemReaction(*rxn1);
633     SparseIntVect<std::uint32_t> *rxn2FP =
634         DifferenceFingerprintChemReaction(*rxn2);
635 
636     TEST_ASSERT(TanimotoSimilarity(*rxn1FP, *rxn2FP) > 0.0);
637     TEST_ASSERT(TanimotoSimilarity(*rxn1FP, *rxn2FP) <= 1.0);
638 
639     delete rxn1;
640     delete rxn2;
641     delete rxn1FP;
642     delete rxn2FP;
643   }
644   {
645     std::string reaction1, reaction2;
646     ChemicalReaction *rxn1, *rxn2;
647 
648     reaction1 = "c1ccccc1>>c1ccncn1";
649     reaction2 = "c1ccccc1>>c1ccncc1";
650     rxn1 = RxnSmartsToChemicalReaction(reaction1, nullptr, true);
651     rxn2 = RxnSmartsToChemicalReaction(reaction2, nullptr, true);
652     TEST_ASSERT(rxn1);
653     TEST_ASSERT(rxn2);
654 
655     ReactionFingerprintParams params;
656     params.fpType = MorganFP;
657 
658     SparseIntVect<std::uint32_t> *rxn1FP =
659         DifferenceFingerprintChemReaction(*rxn1, params);
660     SparseIntVect<std::uint32_t> *rxn2FP =
661         DifferenceFingerprintChemReaction(*rxn2, params);
662 
663     TEST_ASSERT(TanimotoSimilarity(*rxn1FP, *rxn2FP) > 0.0);
664     TEST_ASSERT(TanimotoSimilarity(*rxn1FP, *rxn2FP) <= 1.0);
665 
666     delete rxn1;
667     delete rxn2;
668     delete rxn1FP;
669     delete rxn2FP;
670   }
671   {
672     std::string reaction1, reaction2;
673     ChemicalReaction *rxn1, *rxn2;
674 
675     reaction1 = "c1ccccc1>>c1ccncn1";
676     reaction2 = "c1ccccc1>>c1ccncc1";
677     rxn1 = RxnSmartsToChemicalReaction(reaction1, nullptr, true);
678     rxn2 = RxnSmartsToChemicalReaction(reaction2, nullptr, true);
679     TEST_ASSERT(rxn1);
680     TEST_ASSERT(rxn2);
681 
682     ReactionFingerprintParams params;
683     params.fpType = TopologicalTorsion;
684 
685     SparseIntVect<std::uint32_t> *rxn1FP =
686         DifferenceFingerprintChemReaction(*rxn1, params);
687     SparseIntVect<std::uint32_t> *rxn2FP =
688         DifferenceFingerprintChemReaction(*rxn2, params);
689 
690     TEST_ASSERT(TanimotoSimilarity(*rxn1FP, *rxn2FP) > 0.0);
691     TEST_ASSERT(TanimotoSimilarity(*rxn1FP, *rxn2FP) <= 1.0);
692 
693     delete rxn1;
694     delete rxn2;
695     delete rxn1FP;
696     delete rxn2FP;
697   }
698 }
699 
main()700 int main() {
701   RDLog::InitLogs();
702 
703   BOOST_LOG(rdInfoLog)
704       << "********************************************************\n";
705   BOOST_LOG(rdInfoLog) << "Testing Chemical Reaction Fingerprints \n";
706 
707   testStructuralFingerprintsReaction();
708   testDifferenceFingerprintsReaction();
709 
710   BOOST_LOG(rdInfoLog)
711       << "*******************************************************\n";
712   return (0);
713 }
714