RDKit
Open-source cheminformatics and machine learning.
Loading...
Searching...
No Matches
SynthonSpaceSearch_details.h
Go to the documentation of this file.
1//
2// Copyright (C) David Cosgrove 2024.
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#ifndef RDKIT_SYNTHONSPACESEARCHDETAILS_H
12#define RDKIT_SYNTHONSPACESEARCHDETAILS_H
13
14#include <chrono>
15#include <limits>
16#include <vector>
17
20#include <RDGeneral/export.h>
22
23using Clock = std::chrono::steady_clock;
24using TimePoint = std::chrono::time_point<Clock>;
25
26namespace RDKit {
27class ROMol;
28class ProgressBar;
29namespace SynthonSpaceSearch {
30struct SampleMolRec;
31
32namespace details {
33
35
36// Find all combinations of M things selected from N.
37RDKIT_SYNTHONSPACESEARCH_EXPORT std::vector<std::vector<unsigned int>>
38combMFromN(unsigned int m, unsigned int n);
39// Find all permutations of M things selected from N.
40RDKIT_SYNTHONSPACESEARCH_EXPORT std::vector<std::vector<unsigned int>>
41permMFromN(unsigned int m, unsigned int n);
42
43// Split the molecule into fragments. maxNumFrags gives the maximum number
44// of fragments to be produced in each set. There will a vector of vectors of
45// molecules. Each inner vector contains the fragments from a split molecule.
46// The maxNumFrags will be constrained to the maximum number of synthons in
47// the search space as there's no point making more fragments than that.
48// Any complex query atoms will be stripped out of the fragments and replaced
49// by a simple atom query.
50RDKIT_SYNTHONSPACESEARCH_EXPORT std::vector<std::vector<std::shared_ptr<ROMol>>>
51splitMolecule(const ROMol &query, unsigned int maxNumFrags,
52 const std::uint64_t maxNumFragSets, const TimePoint *endTime,
53 const int numThreads, const FragSetUniquifyMode &uniquifyMode,
54 bool &timedOut);
55// Counts the number of [1*], [2*]...[4*] in the string.
57
58// Return a bitset for each fragment giving the connector patterns
59RDKIT_SYNTHONSPACESEARCH_EXPORT std::vector<boost::dynamic_bitset<>>
60getConnectorPatterns(const std::vector<std::shared_ptr<ROMol>> &fragSet);
61
62// Return a bitset giving the different connector types in this
63// molecule.
65 const std::vector<std::shared_ptr<ROMol>> &fragSet);
66
67// Gets the permutations of connector numbers and the atoms they should
68// be applied to in the molFrags.
69// E.g. if the reaction has 3 connectors, 1, 2 and 3 and the fragged mol has
70// 2, return all permutations of 2 from 3. It's ok if the fragged mol doesn't
71// have all the connections in the reaction, although this may well result in
72// a lot of hits.
74std::vector<std::vector<std::vector<std::pair<Atom *, unsigned int>>>>
75getConnectorPermutations(const std::vector<std::unique_ptr<ROMol>> &molFrags,
76 const boost::dynamic_bitset<> &fragConns,
77 const boost::dynamic_bitset<> &reactionConns);
78
79// As above, but just returns the bitsets for the connector permutations,
80// not the molecules.
82std::vector<std::vector<boost::dynamic_bitset<>>> getConnectorPermutations(
83 const std::vector<boost::dynamic_bitset<>> &fragConnPatts,
84 const boost::dynamic_bitset<> &reactionConns);
85
86// If all bits in one of the bitsets is unset, it means that no fragment matched
87// that synthon. If at least one of the bitsets has a set bit, all products
88// incorporating the synthon with no bits set must match the query so
89// should be used because the query matches products that don't incorporate
90// anything from 1 of the synthon lists. Therefore those bits will all be
91// set on exit. For example, if the synthons are
92// [1*]Nc1c([2*])cccc1 and [1*]=CC=C[2*] and the query is c1ccccc1.
94 std::vector<boost::dynamic_bitset<>> &bitSets);
95
97 const std::vector<boost::dynamic_bitset<>> &bitSets,
98 std::vector<std::vector<size_t>> &outVecs);
99
100// class to step through all combinations of lists of different sizes.
101// returns (0,0,0), (0,0,1), (0,1,0) etc.
103 explicit Stepper(const std::vector<size_t> &sizes) : d_sizes(sizes) {
104 d_currState = std::vector<size_t>(sizes.size(), 0);
105 }
106 void step() {
107 // Don't do anything if we're at the end, but expect an infinite
108 // loop if the user isn't wise to this.
109 if (d_currState[0] == d_sizes[0]) {
110 return;
111 }
112 std::int64_t i = static_cast<std::int64_t>(d_currState.size()) - 1;
113 while (i >= 0) {
114 ++d_currState[i];
115 if (d_currState[0] == d_sizes[0]) {
116 return;
117 }
118 if (d_currState[i] == d_sizes[i]) {
119 d_currState[i] = 0;
120 } else {
121 break;
122 }
123 --i;
124 }
125 }
126 std::vector<size_t> d_currState;
127 std::vector<size_t> d_sizes;
128};
129
130// Return a molecule containing the portions of the molecule starting at
131// each dummy atom and going out up to 3 bonds. There may be more than
132// 1 fragment if there are dummy atoms more than 3 bonds apart, and there
133// may be fragments with more than 1 dummy atom if their dummy atoms fall
134// within 3 bonds of each other. E.g. the molecule [1*]CN(C[2*])Cc1ccccc1
135// will give [1*]CN(C)C[1*]. The 2 dummy atoms are 4 bonds apart, but the
136// fragments overlap. All dummy atoms given isotope 1 whatever they had
137// before.
139 const ROMol &mol);
140
141// Take any query atoms out of the molecule, replacing them with the
142// nearest thing possible. Probably this will just be the atomic
143// number. It doesn't change dummy atoms that have an isotope as
144// these will be connectors, or anything with an AtomType query as
145// they are uncontroversial. Returns true if it did something,
146// false if the molecule was left unchanged.
148
149// Put together a product name in the Enamine style, which uses
150// a semicolon as a separator and has the reagents names followed
151// by the reaction name.
153 const std::string &reactionId, const std::vector<std::string> &fragIds);
155 const std::string &reactionId,
156 const std::vector<const std::string *> &fragIds);
159 const std::vector<size_t> &fragNums);
160// Hash of the product identity — same byte sequence as buildProductName but
161// without allocating the concatenated string. Use as a dedup key.
164 const std::vector<size_t> &fragNums);
165// Zip the fragments together to make a molecule. Assumes the connection
166// points are marking by isotope numbers on dummy atoms.
168 const std::vector<const ROMol *> &synthons);
169
170// Make a map that has all the fragments with the same SMILES
171// in a vector keyed by that SMILES.
172RDKIT_SYNTHONSPACESEARCH_EXPORT std::map<std::string, std::vector<ROMol *>>
173mapFragsBySmiles(std::vector<std::vector<std::shared_ptr<ROMol>>> &fragSets,
174 bool &cancelled);
175
176// Count the number of chiral atoms, both specified and unspecified i.e. any
177// atoms returned by findPotentialStereo. If numExcDummies is not nullptr,
178// it will be sent back with the number of chiral centres excluding those
179// that include 2 or more dummy atoms (which are flagged as chiral if the
180// dummies have different isotopes which will be the case here). They
181// may not be chiral in the final product if the 2 synthons attached are the
182// same. For example in [1*]C([2*])(N)[C@H](O)F with [1*]F and [2*]F, the
183// first C is deemed possibly chiral, but isn't with the 2 F atoms are
184// attached.
186 ROMol &mol, unsigned int *numExcDummies = nullptr);
187
188// Check if there's an atom or bond that findPotentialStereo
189// reports that doesn't have a specified configuration.
191
192// Make sure the shapes are at least simThreshold combination tanimoto apart.
194 double simThreshold);
195
196// Generate conformers for the molecule passed in, including enumerating
197// stereoisomers if requested.
198RDKIT_SYNTHONSPACESEARCH_EXPORT std::vector<std::unique_ptr<RWMol>>
200 const ROMol &mol, unsigned int numConformers, bool enumerateStereo,
203 UserConfGenerator &userConfGenerator,
204 unsigned int maxStereoCenters = std::numeric_limits<unsigned int>::max());
205
206// Trim the molecule down to the minimum needed to do a sensible conformation
207// expansion for the atoms with property molNum=molNum.
209 const ROMol &mol, size_t molNum);
210
211// Make the synthon shapes for the given molecules based on the passed in
212// synthons. The synthon of interest in each molecule is from the
213// synthSetNum vector of the synthons. Works in parallel on the number of
214// threads given in shapeParams.
216 std::vector<std::unique_ptr<SampleMolRec>> &sampleMols,
217 DGeomHelpers::EmbedParameters &dgParams, ShapeBuildParams &shapeBuildParams,
218 std::unique_ptr<ProgressBar> &pbar);
219
221 std::vector<std::pair<const SynthonSpaceHitSet *, std::vector<size_t>>>
222 &toTry);
223
224} // namespace details
225} // namespace SynthonSpaceSearch
226} // namespace RDKit
227
228#endif // RDKIT_SYNTHONSPACESEARCHDETAILS_H
std::chrono::steady_clock Clock
std::chrono::time_point< Clock > TimePoint
RWMol is a molecule class that is intended to be edited.
Definition RWMol.h:32
#define RDKIT_SYNTHONSPACESEARCH_EXPORT
Definition export.h:731
RDKIT_SYNTHONSPACESEARCH_EXPORT std::vector< std::vector< std::vector< std::pair< Atom *, unsigned int > > > > getConnectorPermutations(const std::vector< std::unique_ptr< ROMol > > &molFrags, const boost::dynamic_bitset<> &fragConns, const boost::dynamic_bitset<> &reactionConns)
RDKIT_SYNTHONSPACESEARCH_EXPORT std::size_t buildProductHash(const RDKit::SynthonSpaceSearch::SynthonSpaceHitSet *hitset, const std::vector< size_t > &fragNums)
RDKIT_SYNTHONSPACESEARCH_EXPORT std::unique_ptr< RWMol > trimSampleMol(const ROMol &mol, size_t molNum)
RDKIT_SYNTHONSPACESEARCH_EXPORT bool removeQueryAtoms(RWMol &mol)
RDKIT_SYNTHONSPACESEARCH_EXPORT void bitSetsToVectors(const std::vector< boost::dynamic_bitset<> > &bitSets, std::vector< std::vector< size_t > > &outVecs)
RDKIT_SYNTHONSPACESEARCH_EXPORT void makeShapesFromMols(std::vector< std::unique_ptr< SampleMolRec > > &sampleMols, DGeomHelpers::EmbedParameters &dgParams, ShapeBuildParams &shapeBuildParams, std::unique_ptr< ProgressBar > &pbar)
RDKIT_SYNTHONSPACESEARCH_EXPORT bool checkTimeOut(const TimePoint *endTime)
RDKIT_SYNTHONSPACESEARCH_EXPORT int countConnections(const ROMol &mol)
RDKIT_SYNTHONSPACESEARCH_EXPORT boost::dynamic_bitset getConnectorPattern(const std::vector< std::shared_ptr< ROMol > > &fragSet)
RDKIT_SYNTHONSPACESEARCH_EXPORT std::vector< std::unique_ptr< RWMol > > generateIsomerConformers(const ROMol &mol, unsigned int numConformers, bool enumerateStereo, const EnumerateStereoisomers::StereoEnumerationOptions &enumOpts, DGeomHelpers::EmbedParameters &dgParams, UserConfGenerator &userConfGenerator, unsigned int maxStereoCenters=std::numeric_limits< unsigned int >::max())
RDKIT_SYNTHONSPACESEARCH_EXPORT unsigned int countChiralAtoms(ROMol &mol, unsigned int *numExcDummies=nullptr)
RDKIT_SYNTHONSPACESEARCH_EXPORT std::vector< std::vector< unsigned int > > permMFromN(unsigned int m, unsigned int n)
RDKIT_SYNTHONSPACESEARCH_EXPORT std::map< std::string, std::vector< ROMol * > > mapFragsBySmiles(std::vector< std::vector< std::shared_ptr< ROMol > > > &fragSets, bool &cancelled)
RDKIT_SYNTHONSPACESEARCH_EXPORT std::unique_ptr< ROMol > buildConnRegion(const ROMol &mol)
RDKIT_SYNTHONSPACESEARCH_EXPORT bool hasUnspecifiedStereo(ROMol &mol)
RDKIT_SYNTHONSPACESEARCH_EXPORT std::vector< std::vector< std::shared_ptr< ROMol > > > splitMolecule(const ROMol &query, unsigned int maxNumFrags, const std::uint64_t maxNumFragSets, const TimePoint *endTime, const int numThreads, const FragSetUniquifyMode &uniquifyMode, bool &timedOut)
RDKIT_SYNTHONSPACESEARCH_EXPORT std::vector< std::vector< unsigned int > > combMFromN(unsigned int m, unsigned int n)
RDKIT_SYNTHONSPACESEARCH_EXPORT void pruneShapes(ShapeSet &shapeSet, double simThreshold)
RDKIT_SYNTHONSPACESEARCH_EXPORT std::unique_ptr< ROMol > buildProduct(const std::vector< const ROMol * > &synthons)
RDKIT_SYNTHONSPACESEARCH_EXPORT void sortAndUniquifyToTry(std::vector< std::pair< const SynthonSpaceHitSet *, std::vector< size_t > > > &toTry)
RDKIT_SYNTHONSPACESEARCH_EXPORT std::string buildProductName(const std::string &reactionId, const std::vector< std::string > &fragIds)
RDKIT_SYNTHONSPACESEARCH_EXPORT void expandBitSet(std::vector< boost::dynamic_bitset<> > &bitSets)
RDKIT_SYNTHONSPACESEARCH_EXPORT std::vector< boost::dynamic_bitset<> > getConnectorPatterns(const std::vector< std::shared_ptr< ROMol > > &fragSet)
std::vector< std::unique_ptr< SynthonShapeInput > > ShapeSet
std::function< std::unique_ptr< RWMol >( const std::string &smiles, unsigned int numConformers)> UserConfGenerator
Std stuff.
Parameter object for controlling embedding.
Definition Embedder.h:125