RDKit
Open-source cheminformatics and machine learning.
Toggle main menu visibility
Loading...
Searching...
No Matches
SynthonSpaceShapeSearcher.h
Go to the documentation of this file.
1
//
2
// Copyright (C) David Cosgrove 2025.
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
11
// This file declares a concrete class derived from SynthonSpaceSearcher
12
// that does shape similarity searching of the SynthonSpace using
13
// the GaussianShape module.
14
15
#ifndef SYNTHONSPACESHAPESEARCHER_H
16
#define SYNTHONSPACESHAPESEARCHER_H
17
18
#include <
RDGeneral/export.h
>
19
#include <
GraphMol/SynthonSpaceSearch/SynthonShapeInput.h
>
20
#include <
GraphMol/SynthonSpaceSearch/SynthonSpaceSearcher.h
>
21
#include <
GraphMol/SynthonSpaceSearch/SynthonSpaceSearch_details.h
>
22
23
namespace
RDKit::SynthonSpaceSearch
{
24
25
// A hash function used to hash a pair of any kind. Taken from
26
// https://stackoverflow.com/questions/32685540/why-cant-i-compile-an-unordered-map-with-a-pair-as-key
27
// But with the hash combining from
28
// https://stackoverflow.com/questions/5889238/why-is-xor-the-default-way-to-combine-hashes/27952689#27952689
29
// Which is apparently effectively how boost::hash_combine does it.
30
struct
hash_address_pair
{
31
size_t
operator()
(
const
std::pair<const void *, const void *> &p)
const
{
32
// Hash the first element
33
size_t
hash1 = std::hash<const void *>{}(p.first);
34
// Hash the second element
35
size_t
hash2 = std::hash<const void *>{}(p.second);
36
// Combine the two hash values
37
return
hash1 ^ (hash2 + 0x517cc1b727220a95 + (hash1 << 6) + (hash1 >> 2));
38
}
39
};
40
41
// Used for storing the pre-computed similarities between fragments and
42
// synthons. The actual type of the first address in the pair will vary,
43
// the second should always be Synthon *. There's an entry only if
44
// the fragment->synthon similarity exceeded the threshold. Stores the
45
// combination score, the number of the shape and the transformation
46
// to apply to the shape to get the overlay that gave the score.
47
using
SynthonOverlay
=
48
std::tuple<double, unsigned int, std::shared_ptr<RDGeom::Transform3D>>;
49
using
FragSynthonSims
=
50
std::unordered_map<std::pair<const void *, const void *>,
SynthonOverlay
,
51
hash_address_pair
>;
52
53
// Concrete class that does the search by Gaussian shape similarity.
54
class
SynthonSpaceShapeSearcher
:
public
SynthonSpaceSearcher
{
55
public
:
56
SynthonSpaceShapeSearcher
() =
delete
;
57
SynthonSpaceShapeSearcher
(
const
ROMol
&query,
58
const
SynthonSpaceSearchParams
¶ms,
59
SynthonSpace
*space);
60
61
std::vector<std::unique_ptr<SynthonSpaceHitSet>>
searchFragSet
(
62
const
std::vector<std::shared_ptr<ROMol>> &fragSet,
63
const
SynthonSet
&reaction)
const override
;
64
65
bool
verifyHit
(
ROMol
&hit,
const
std::string &rxnId,
66
const
std::vector<const std::string *> &synthNames)
override
;
67
68
// Use d_fragSynthonSims to decide if the fragment matched the
69
// Synthon.
70
bool
fragMatchedSynthon
(
const
void
*frag,
const
void
*synthon,
71
SynthonOverlay
&sim)
const
;
72
bool
hasPrecomputedSims
()
const
{
return
!d_fragSynthonSims.empty(); }
73
74
protected
:
75
bool
quickVerify
(
const
SynthonSpaceHitSet
*hitset,
76
const
std::vector<size_t> &synthNums)
const override
;
77
double
approxSimilarity
(
const
SynthonSpaceHitSet
*hitset,
78
const
std::vector<size_t> &synthNums)
const override
;
79
// Build the hit, doing its best to line the synthons up correctly.
80
// It may not do a great job, however for at least 2 reasons.
81
// The synthon may not match a fragment, in which case there is no
82
// good way of lining it up on the query. Also, molzip lines the
83
// fragments up using the bond vectors to the dummy atoms, but this
84
// fails if it's building a ring. The product geometry should be
85
// checked for bad bond lengths.
86
std::unique_ptr<ROMol>
buildHit
(
87
const
SynthonSpaceHitSet
*hitset,
const
std::vector<size_t> &synthNums,
88
std::vector<const std::string *> &synthNames)
const override
;
89
90
private
:
91
// Shape for the query - only ever 1 conformer.
92
std::unique_ptr<SynthonShapeInput> dp_queryShape;
93
// These are the fragment shapes for this search, derived from
94
// d_query. The shapes in d_fragShapes are sorted on the address
95
// of the corresponding fragment. d_fragShapesPool is never read,
96
// it is just used a repository of the shapes for the duration of
97
// the search.
98
std::vector<std::unique_ptr<SynthonShapeInput>> d_fragShapesPool;
99
std::vector<std::pair<void *, SynthonShapeInput *>> d_fragShapes;
100
101
// Precomputed similarities between fragments and synthons. This
102
// speeds things up because synthons are re-used and for the shape
103
// search we have to calculate the similarity between every query
104
// fragment and all the synthons in each SynthonSet. Fingerprint
105
// and RASCAL searching can dismiss a lot of fragment/synthon pairs
106
// as not matching without calculating the full similarity so doing
107
// the full set of similarity calculations up front slows things
108
// down for them.
109
FragSynthonSims
d_fragSynthonSims;
110
111
bool
extraSearchSetup(
112
std::vector<std::vector<std::shared_ptr<ROMol>>> &fragSets,
113
const
TimePoint
*endTime)
override
;
114
115
void
buildQueryShape(
const
ROMol
&mol,
116
std::vector<GaussianShape::CustomFeature> &allFeatures);
117
118
// Fill in the d_fragSynthonSims map.
119
bool
computeFragSynthonSims(
120
const
TimePoint
*endTime,
121
std::unordered_map<void *, unsigned int> &minFragSetSize);
122
123
void
processToTrySet(
124
std::vector<std::pair<
const
SynthonSpaceHitSet
*, std::vector<size_t>>>
125
&toTry,
126
const
TimePoint
*endTime, std::vector<std::unique_ptr<ROMol>> &results,
127
std::atomic<std::int64_t> &numHitsFound,
128
std::uint64_t &numPossHitsWritten)
override
;
129
130
// Given the frag, return the corresponding frag shape. Returns nullptr
131
// if not found.
132
SynthonShapeInput
*getFragShape(
const
void
*frag)
const
;
133
};
134
}
// namespace RDKit::SynthonSpaceSearch
135
#endif
// SYNTHONSPACESHAPESEARCHER_H
SynthonShapeInput.h
SynthonSpaceSearch_details.h
TimePoint
std::chrono::time_point< Clock > TimePoint
Definition
SynthonSpaceSearch_details.h:24
SynthonSpaceSearcher.h
RDKit::ROMol
Definition
ROMol.h:344
RDKit::SynthonSpaceSearch::SynthonSet
Definition
SynthonSet.h:51
RDKit::SynthonSpaceSearch::SynthonShapeInput
Definition
SynthonShapeInput.h:33
RDKit::SynthonSpaceSearch::SynthonSpaceSearcher::SynthonSpaceSearcher
SynthonSpaceSearcher()=delete
RDKit::SynthonSpaceSearch::SynthonSpaceShapeSearcher::fragMatchedSynthon
bool fragMatchedSynthon(const void *frag, const void *synthon, SynthonOverlay &sim) const
RDKit::SynthonSpaceSearch::SynthonSpaceShapeSearcher::searchFragSet
std::vector< std::unique_ptr< SynthonSpaceHitSet > > searchFragSet(const std::vector< std::shared_ptr< ROMol > > &fragSet, const SynthonSet &reaction) const override
RDKit::SynthonSpaceSearch::SynthonSpaceShapeSearcher::quickVerify
bool quickVerify(const SynthonSpaceHitSet *hitset, const std::vector< size_t > &synthNums) const override
RDKit::SynthonSpaceSearch::SynthonSpaceShapeSearcher::verifyHit
bool verifyHit(ROMol &hit, const std::string &rxnId, const std::vector< const std::string * > &synthNames) override
RDKit::SynthonSpaceSearch::SynthonSpaceShapeSearcher::hasPrecomputedSims
bool hasPrecomputedSims() const
Definition
SynthonSpaceShapeSearcher.h:72
RDKit::SynthonSpaceSearch::SynthonSpaceShapeSearcher::SynthonSpaceShapeSearcher
SynthonSpaceShapeSearcher(const ROMol &query, const SynthonSpaceSearchParams ¶ms, SynthonSpace *space)
RDKit::SynthonSpaceSearch::SynthonSpaceShapeSearcher::SynthonSpaceShapeSearcher
SynthonSpaceShapeSearcher()=delete
RDKit::SynthonSpaceSearch::SynthonSpaceShapeSearcher::buildHit
std::unique_ptr< ROMol > buildHit(const SynthonSpaceHitSet *hitset, const std::vector< size_t > &synthNums, std::vector< const std::string * > &synthNames) const override
RDKit::SynthonSpaceSearch::SynthonSpaceShapeSearcher::approxSimilarity
double approxSimilarity(const SynthonSpaceHitSet *hitset, const std::vector< size_t > &synthNums) const override
RDKit::SynthonSpaceSearch::SynthonSpace
Definition
SynthonSpace.h:56
export.h
RDKit::SynthonSpaceSearch
Definition
MemoryMappedFileReader.h:19
RDKit::SynthonSpaceSearch::SynthonOverlay
std::tuple< double, unsigned int, std::shared_ptr< RDGeom::Transform3D > > SynthonOverlay
Definition
SynthonSpaceShapeSearcher.h:47
RDKit::SynthonSpaceSearch::FragSynthonSims
std::unordered_map< std::pair< const void *, const void * >, SynthonOverlay, hash_address_pair > FragSynthonSims
Definition
SynthonSpaceShapeSearcher.h:49
RDKit::SynthonSpaceSearch::SynthonSpaceHitSet
Definition
SynthonSpaceHitSet.h:27
RDKit::SynthonSpaceSearch::SynthonSpaceSearchParams
Definition
SynthonSpaceSearchHelpers.h:37
RDKit::SynthonSpaceSearch::hash_address_pair
Definition
SynthonSpaceShapeSearcher.h:30
RDKit::SynthonSpaceSearch::hash_address_pair::operator()
size_t operator()(const std::pair< const void *, const void * > &p) const
Definition
SynthonSpaceShapeSearcher.h:31
GraphMol
SynthonSpaceSearch
SynthonSpaceShapeSearcher.h
Generated on
for RDKit by
1.17.0