-
Notifications
You must be signed in to change notification settings - Fork 28
/
CoordgenMinimizer.h
400 lines (327 loc) · 13.9 KB
/
CoordgenMinimizer.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
/*
Contributors: Nicola Zonta
Copyright Schrodinger, LLC. All rights reserved
*/
#ifndef COORDGEN_MINIMIZER_H
#define COORDGEN_MINIMIZER_H
#include "CoordgenConfig.hpp"
#include <iostream>
#include <map>
#include <set>
#include <vector>
class sketcherMinimizerInteraction;
class sketcherMinimizerStretchInteraction;
class sketcherMinimizerBendInteraction;
class sketcherMinimizerClashInteraction;
class sketcherMinimizerMolecule;
class sketcherMinimizerResidue;
class sketcherMinimizerResidueInteraction;
class sketcherMinimizerAtom;
class sketcherMinimizerBond;
class sketcherMinimizerRing;
class sketcherMinimizerFragment;
class sketcherMinimizerPointF;
class CoordgenFragmentDOF;
class CoordgenMinimizer;
/* class to manage the solutions to a minimization problem. Each solution is a
vector that contains values for each of the degrees of freedom of the problem
*/
class CoordgenDOFSolutions
{
public:
CoordgenDOFSolutions(const CoordgenMinimizer* minimizer,
sketcherMinimizerMolecule* molecule,
std::vector<CoordgenFragmentDOF*> allDofs)
: m_minimizer(minimizer), m_molecule(molecule),
m_allDofs(std::move(allDofs))
{
}
/*
calculate the value of the scoring function on the currently loaded
solution
*/
float scoreCurrentSolution();
/*
get the solution that is currently loaded
*/
std::vector<short unsigned int> getCurrentSolution();
/*
load the given solution (i.e. set each degree of freedom in the molecule to
the given value)
*/
void loadSolution(const std::vector<short unsigned int>& solution);
/*
return the best scoring solution that has been found so far
*/
std::pair<std::vector<short unsigned int>, float> findBestSolution() const;
/*
check if the given solution has already been scored
*/
bool hasSolution(const std::vector<short unsigned int>& solution);
std::vector<CoordgenFragmentDOF*>& getAllDofs() { return m_allDofs; }
private:
const CoordgenMinimizer* m_minimizer;
sketcherMinimizerMolecule* m_molecule;
std::map<std::vector<short unsigned int>, float> m_solutions;
std::vector<CoordgenFragmentDOF*> m_allDofs;
};
/*
minimizer class that resolves clashes in a molecule. It can explore degrees of
freedom conformations (e.g. flip around single bonds) and perform a force-field
based free atom minimization
*/
class EXPORT_COORDGEN CoordgenMinimizer
{
public:
CoordgenMinimizer();
~CoordgenMinimizer();
/* clear all the interactions loaded in the minimizer and free memory */
void clearInteractions();
/* run a force-field based minimization */
void run();
/* Apply forces and take a step in the minimization. Returns false if
* converged, true if not. */
bool applyForces(float maxd = 3);
/* run a force-field based minimization on residues only */
void minimizeResidues();
/* run a force-field based minimization on the given molecule */
void minimizeMolecule(sketcherMinimizerMolecule* molecule);
/* solve clashes of residues in a protein-protein interaction LID */
void minimizeProteinOnlyLID(
const std::map<std::string, std::vector<sketcherMinimizerResidue*>>&
chains);
/* setup constraints and run a force-field based minimization */
void minimizeAll();
/* setup constraints on residues only */
void setupInteractionsOnlyResidues();
/* setup constraints on residues in a protein-protein interaction scenario
*/
void setupInteractionsProteinOnly(
const std::map<std::string, std::vector<sketcherMinimizerResidue*>>&
chains);
/* setup all constraints */
void setupInteractions(bool intrafragmentClashes = false);
/* setup all constraints of given molecule */
void addInteractionsOfMolecule(sketcherMinimizerMolecule* molecule,
bool intrafragmentClashes = false);
/* score the forcefield value of the current conformation */
float scoreInteractions();
/* add a list of intermolecular clash constraints between two given
* molecules
*/
bool findIntermolecularClashes(sketcherMinimizerMolecule* mol1,
sketcherMinimizerMolecule* mol2,
float threshold);
/* add a list of intermolecular clash constraints between given molecules */
bool findIntermolecularClashes(
const std::vector<sketcherMinimizerMolecule*>& mols, float threshold);
/* precision of the minimization. Higher values result in higher times and
* better results */
float getPrecision() const;
void setPrecision(float f);
/* score all clashes of the given molecule */
float
scoreClashes(sketcherMinimizerMolecule* molecule,
bool residueInteractions = false,
bool scoreProximityRelationsOnOppositeSides = true) const;
/* score the penalty for intersecting bonds */
float scoreCrossBonds(sketcherMinimizerMolecule* molecule,
bool residueInteractions = false) const;
/* score the penalty for degrees of freedom set to non-ideal values */
float scoreDofs(sketcherMinimizerMolecule* molecule) const;
/* score the penalty of atoms placed inside rings */
float scoreAtomsInsideRings() const;
/* assign a penalty if a molecule (A) is bound to another (B) with more than
* a proximity relation and they are on different sides of A and involving
* different fragments. This forces the algorithm to look for poses where
* all the atoms of A that have proximity relations with B are on the same
* side of A. */
float scoreProximityRelationsOnOppositeSides() const;
/*
run the minimization and return true if the result is considered ideal
*/
bool avoidClashes();
/*
run the minimization on the given molecule. Returns true if the result is
considered ideal
*/
bool avoidClashesOfMolecule(
sketcherMinimizerMolecule* molecule,
const std::vector<sketcherMinimizerInteraction*>& extraInteractions =
std::vector<sketcherMinimizerInteraction*>());
/*
set up the DoF list and run a minimization on the given molecule
*/
bool flipFragments(sketcherMinimizerMolecule* molecule, float& clashE);
/*
run a search on the degrees of freedom, exploring combinations of degrees
of freedom
*/
bool runLocalSearch(sketcherMinimizerMolecule* molecule,
const std::vector<CoordgenFragmentDOF*>& dofs,
int levels, float& clashE,
CoordgenDOFSolutions& solutions);
/*
iteratively grow the pool of solutions by mutating the best scoring one by
one degree of freedom
*/
bool growSolutions(
std::set<std::vector<short unsigned int>>& allScoredSolutions,
int& currentTier,
std::map<std::vector<short unsigned int>, float>& growingSolutions,
CoordgenDOFSolutions& solutions, float& bestScore);
/*
run the search to find good scoring solutions to the problem. Each degree
of freedom has a tier value that ensures that simpler and more aesthetic
pleasing ones (e.g. flipping fragments) are searched before more complex
ones (i.e. putting substituents inside macrocycles). This is alternative
and preferred to runExhaustiveSearch and runLocalSearch
*/
bool runSearch(int tier, CoordgenDOFSolutions& solutions);
/* build a list of tuples of the given order representing all combinations
* of dofs */
std::vector<std::vector<CoordgenFragmentDOF*>>
buildTuplesOfDofs(const std::vector<CoordgenFragmentDOF*>& dofs,
unsigned int order) const;
/*
run en exhaustive search on all combinations of DoFs.
*/
bool runExhaustiveSearch(sketcherMinimizerMolecule* molecule,
std::vector<CoordgenFragmentDOF*> dofs,
float& clashE, CoordgenDOFSolutions& solutions);
void runExhaustiveSearchLevel(
sketcherMinimizerMolecule* molecule,
const std::vector<CoordgenFragmentDOF*>::iterator& iterator,
std::vector<CoordgenFragmentDOF*>& dofs, float& bestResult, bool& abort,
CoordgenDOFSolutions& solutions);
/* return true if the given bonds clash */
bool bondsClash(sketcherMinimizerBond* bond,
sketcherMinimizerBond* bond2) const;
/*
quick function to avoid clashes of terminal atoms without running a
minimization
*/
void avoidTerminalClashes(sketcherMinimizerMolecule* molecule,
float& clashE);
/*
check if the ring system cannot be drown with regular polygons and needs a
FF based minimization
*/
static void
maybeMinimizeRings(const std::vector<sketcherMinimizerRing*>& rings);
/*
avoid clashes of terminal atoms of the same fragment without running a
minimization
*/
static void avoidInternalClashes(sketcherMinimizerFragment* fragment);
/*
assign coordinates to each atom from the current values of DoFs of the
fragments
*/
void buildFromFragments(bool firstTime = false) const;
/*
assign coordinates to each atom from the current values of DoFs of the
fragments
*/
void buildMoleculeFromFragments(sketcherMinimizerMolecule* molecule,
bool firstTime = false) const;
/* find a list of carbons from the backbone C=O of a peptide */
std::set<sketcherMinimizerAtom*>
getChetoCs(const std::vector<sketcherMinimizerAtom*>& allAtoms) const;
/* find a list of nitrogens from the backbon NH of a peptide */
std::set<sketcherMinimizerAtom*>
getAminoNs(const std::vector<sketcherMinimizerAtom*>& allAtoms) const;
/* find a list of alpha carbons of a peptide */
std::set<sketcherMinimizerAtom*>
getAlphaCs(const std::vector<sketcherMinimizerAtom*>& allAtoms,
const std::set<sketcherMinimizerAtom*>& chetoCs,
const std::set<sketcherMinimizerAtom*>& aminoNs) const;
/* check the atom for clashes with other atoms */
static void checkForClashes(sketcherMinimizerAtom* a);
/*
return true if atoms have NaN coordinates
*/
static bool
hasNaNCoordinates(const std::vector<sketcherMinimizerAtom*>& atoms);
bool hasNaNCoordinates();
/*
return true if the atom has valid 3d coordinates
*/
static bool
hasValid3DCoordinates(const std::vector<sketcherMinimizerAtom*>& atoms);
/* use 3d coordinates in 2d (e.g. when a reasonable 2d structure cannot be
* found) */
static void
fallbackOn3DCoordinates(const std::vector<sketcherMinimizerAtom*>& atoms);
/*
add the given constraint to the minimizer
*/
void addExtraInteraction(sketcherMinimizerMolecule* molecule,
sketcherMinimizerInteraction* interaction);
std::vector<sketcherMinimizerAtom*> m_atoms;
std::vector<sketcherMinimizerBond*> m_bonds;
bool m_evenAngles;
std::vector<sketcherMinimizerResidue*> m_residues;
std::vector<sketcherMinimizerResidueInteraction*> m_residueInteractions;
std::vector<sketcherMinimizerFragment*> m_fragments;
std::vector<sketcherMinimizerMolecule*> m_molecules;
std::vector<float> energy_list;
std::vector<std::vector<sketcherMinimizerPointF>> all_coordinates;
bool skipMinimization, skipAvoidClashes, skipFlipFragments,
m_scoreResidueInteractions;
const std::vector<sketcherMinimizerBendInteraction*>& getBendInteractions() const {return _bendInteractions;};
const std::vector<sketcherMinimizerStretchInteraction*>& getStretchInteractions() const {return _stretchInteractions;};
const std::vector<sketcherMinimizerInteraction*>& getInteractions() const {return _interactions;};
/*
add clash constraints of the given molecule
*/
void addClashInteractionsOfMolecule(sketcherMinimizerMolecule* molecule,
bool intrafragmentClashes);
/*
add stretch constraints of the given molecule
*/
void addStretchInteractionsOfMolecule(sketcherMinimizerMolecule* molecule);
/*
add angle bend constraints of the given molecule
*/
void addBendInteractionsOfMolecule(sketcherMinimizerMolecule* molecule);
/*
add constraints to avoid deviating from constrained coordinates (e.g. for
alignment)
*/
void
addConstrainedInteractionsOfMolecule(sketcherMinimizerMolecule* molecule);
/*
add constraints to avoid chiral inversion of the given molecule
*/
void addChiralInversionConstraintsOfMolecule(
sketcherMinimizerMolecule* molecule);
/*
add constraints to keep peptide chains linear
*/
void addPeptideBondInversionConstraintsOfMolecule(
sketcherMinimizerMolecule* molecule);
private:
/*
get lists of four atoms that form a chain and are each present in one of
the four sets respectively
*/
void getFourConsecutiveAtomsThatMatchSequence(
std::vector<std::vector<sketcherMinimizerAtom*>>&
consecutiveAtomsGroups,
const std::set<sketcherMinimizerAtom*>& firstSet,
const std::set<sketcherMinimizerAtom*>& secondSet,
const std::set<sketcherMinimizerAtom*>& thirdSet,
const std::set<sketcherMinimizerAtom*>& fourthSet) const;
std::vector<sketcherMinimizerInteraction*> _interactions;
std::vector<sketcherMinimizerStretchInteraction*> _stretchInteractions;
std::vector<sketcherMinimizerBendInteraction*> _bendInteractions;
std::vector<sketcherMinimizerInteraction*> _intramolecularClashInteractions;
std::vector<sketcherMinimizerInteraction*> _extraInteractions;
std::map<sketcherMinimizerMolecule*,
std::vector<sketcherMinimizerInteraction*>>
_extraInteractionsOfMolecule;
unsigned int m_maxIterations;
float m_precision;
};
#endif /* defined(COORDGEN_MINIMIZER_H) */