-
Notifications
You must be signed in to change notification settings - Fork 28
/
sketcherMinimizerAtom.h
277 lines (226 loc) · 9.76 KB
/
sketcherMinimizerAtom.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
/*
* sketcherMinimizerAtom.h
*
* Created by Nicola Zonta on 13/04/2010.
* Copyright Schrodinger, LLC. All rights reserved.
*
*/
#ifndef sketcherMINIMIZERATOM_H
#define sketcherMINIMIZERATOM_H
// #include <sketcherMinimizerPointF>
#include "CoordgenConfig.hpp"
#include "sketcherMinimizerMaths.h"
#include <iostream>
#include <map>
#include <vector>
static const int COORDINATES_LIMIT = 10000000;
static const int INVALID_COORDINATES = COORDINATES_LIMIT + 1;
class sketcherMinimizerBond;
class sketcherMinimizerFragment;
class sketcherMinimizerRing;
class sketcherMinimizerMolecule;
class sketcherMinimizerAtom;
typedef struct {
sketcherMinimizerAtom* a;
unsigned int priority;
} sketcherMinimizerAtomPriority;
struct sketcherMinimizerAtomChiralityInfo {
enum sketcherMinimizerChirality {
clockwise,
counterClockwise,
unspecified
};
sketcherMinimizerAtom* lookingFrom = nullptr;
sketcherMinimizerAtom* atom1 = nullptr;
sketcherMinimizerAtom* atom2 = nullptr;
sketcherMinimizerChirality direction = unspecified;
};
/* structure to represent an atom in Cahn–Ingold–Prelog priorities assignment */
struct CIPAtom {
CIPAtom(std::vector<std::pair<int, sketcherMinimizerAtom*>> us,
sketcherMinimizerAtom* dad,
std::vector<sketcherMinimizerAtom*> allPars,
std::map<sketcherMinimizerAtom*, int>* scors,
std::map<sketcherMinimizerAtom*, std::vector<int>>* meds,
std::map<sketcherMinimizerAtom*, int>* visits
)
: theseAtoms(std::move(us)), parent(dad),
allParents(std::move(allPars)), scores(scors), visited(visits),
medals(meds)
{
}
bool operator<(const CIPAtom& rhs) const;
bool operator==(const CIPAtom& rhs) const;
bool isBetter(CIPAtom& rhs,
std::map<sketcherMinimizerAtom*, unsigned int>* m) const;
std::vector<std::pair<int, sketcherMinimizerAtom*>>
theseAtoms; // NULL if dummy
sketcherMinimizerAtom* parent;
std::vector<sketcherMinimizerAtom*> allParents;
std::map<sketcherMinimizerAtom*, int>* scores;
std::map<sketcherMinimizerAtom*, int>* visited;
std::map<sketcherMinimizerAtom*, std::vector<int>>* medals;
private:
friend std::ostream& operator<<(std::ostream& os, const CIPAtom& a);
};
/* class to represent an atom */
class EXPORT_COORDGEN sketcherMinimizerAtom
{
public:
sketcherMinimizerAtom();
virtual ~sketcherMinimizerAtom();
bool crossLayout; // atoms with 4 substituents displayed in a cross style
// (such as S in sulphate)
bool fixed, constrained, rigid;
bool isSharedAndInner; // shared by two rings and needs to be drawn inside a
// ring
bool hidden;
int atomicNumber, charge, _valence, _generalUseN, _generalUseN2;
int m_chmN; // idx of the corresponding ChmAtom if molecule comes from 3d
bool _generalUseVisited, _generalUseVisited2;
bool m_clockwiseInvert;
bool m_ignoreRingChirality;
std::vector<int> m_RSPriorities;
int _implicitHs = -1;
sketcherMinimizerMolecule* molecule;
sketcherMinimizerFragment* fragment;
void setFragment(sketcherMinimizerFragment* fragmentToSet)
{
fragment = fragmentToSet;
}
sketcherMinimizerFragment* getFragment() const { return fragment; }
const std::vector<sketcherMinimizerBond*>& getBonds() const
{
return bonds;
}
const std::vector<sketcherMinimizerRing*>& getRings() const
{
return rings;
}
sketcherMinimizerMolecule* getMolecule() const { return molecule; }
/*
Find all connected atoms, pruning the search at the excludedAtom."
This function assumes that the bond between this atom and excludedAtom
is not part of a ring.
*/
std::vector<sketcherMinimizerAtom*>
getSubmolecule(sketcherMinimizerAtom* excludedAtom);
std::vector<sketcherMinimizerAtom*> neighbors;
std::vector<sketcherMinimizerBond*> bonds;
std::vector<sketcherMinimizerAtom*> residueInteractionPartners;
std::vector<sketcherMinimizerBond*> residueInteractions;
std::vector<sketcherMinimizerRing*> rings;
float m_pseudoZ;
float m_x3D;
float m_y3D;
float m_z3D;
bool m_isClashing, m_isWaterMap;
float m_pocketDistance;
bool needsCheckForClashes;
bool m_isLigand;
bool visited, coordinatesSet;
bool isR; // stereochemistry
bool hasStereochemistrySet, m_isStereogenic;
bool _hasRingChirality; // used to keep track of cyclohexane cis/trans
// chirality
/* write coordinates to atom */
void setCoordinates(sketcherMinimizerPointF coords);
/* check that the atom has no double bonds possibly involved in E/Z
* stereochemistry */
bool hasNoStereoActiveBonds() const;
const sketcherMinimizerPointF& getCoordinates() const
{
return coordinates;
}
int getAtomicNumber() const { return atomicNumber; }
void setAtomicNumber(int number) { atomicNumber = number; }
void setStereoChemistry(sketcherMinimizerAtomChiralityInfo info)
{
m_chiralityInfo = info;
}
/* write template coordinates to atom */
void setCoordinatesToTemplate() { setCoordinates(templateCoordinates); }
sketcherMinimizerPointF coordinates;
sketcherMinimizerPointF templateCoordinates;
sketcherMinimizerPointF force;
/* return the expected valence for the atom */
unsigned int expectedValence(unsigned int atomicNumber) const;
bool canBeChiral() const; // checks if the atom can have 4 substituents (one
// can be implicit H). Doesn't actually check if
// two of them are the same, so can return true
// for achiral centers
/* return true if this and at2 share a bond */
bool isNeighborOf(sketcherMinimizerAtom* at2) const
{
for (auto& neighbor : at2->neighbors) {
if (neighbor == this) {
return true;
}
}
return false;
}
sketcherMinimizerAtomChiralityInfo::sketcherMinimizerChirality
getRelativeStereo(sketcherMinimizerAtom* lookingFrom,
sketcherMinimizerAtom* atom1,
sketcherMinimizerAtom* atom2);
bool setAbsoluteStereoFromChiralityInfo();
/* if this atom and the given one share a bond, return it */
sketcherMinimizerBond* bondTo(sketcherMinimizerAtom* at) const;
/* return all bonded atoms, ordered as they appear clockwise around this */
std::vector<sketcherMinimizerAtom*> clockwiseOrderedNeighbors() const;
int findHsNumber() const;
void writeStereoChemistry(); // assigns up-down bond flags based on isR and
// hasStereochemistrySet
/* return true if the two sequences represent the same isomer */
static bool matchCIPSequence(std::vector<int>& v1, std::vector<int>& v2);
/* calculate CIP priorities and assign them */
static bool
setCIPPriorities(std::vector<sketcherMinimizerAtomPriority>& atomPriorities,
sketcherMinimizerAtom* center);
static void orderAtomPriorities(
std::vector<sketcherMinimizerAtomPriority>& atomPriorities,
sketcherMinimizerAtom* center); // orders trying to keep long chains in
// position 2 and 3 and side
// substituents in 1 and 4
/* return which between at1 and at2 has higher CIP priority. Returns NULL if
* they have the same */
static sketcherMinimizerAtom* CIPPriority(sketcherMinimizerAtom* at1,
sketcherMinimizerAtom* at2,
sketcherMinimizerAtom* center);
/* consider one additional level of bound atoms in the CIP algorithm to
* break a tie */
static std::vector<CIPAtom> expandOneLevel(std::vector<CIPAtom>& oldV);
/* if any ties between parent atoms was solved, assign two different scores
to them. Also clear the medals for the next iteration */
static void finalizeScores(std::vector<CIPAtom>& v);
/* medals are used to mark parent atoms according to the priorities of their
children and also their numbers. */
static void assignMedals(std::vector<CIPAtom>& v);
/* first atom will be the highest priority, subsequent will be based on
* atoms that have already been picked, giving priorities to branches that
* have been already been visited. friendsMask keeps track of parents that
* have a child that has been already selected */
static void chooseFirstAndSortAccordingly(std::vector<CIPAtom>& V);
/* if the two atoms share a ring, return it */
static sketcherMinimizerRing*
shareARing(const sketcherMinimizerAtom* atom1,
const sketcherMinimizerAtom* atom2);
/* mirror the coordinates of at wrt bond */
static void mirrorCoordinates(sketcherMinimizerAtom* at,
const sketcherMinimizerBond* bond);
/* return the stereochemistry set in the wedges around the atom. 0 if not
* assigned, 1 if R, -1 if S */
int readStereochemistry(bool readOnly = false);
/* return a direction perpendicular to the atom's bonds average */
sketcherMinimizerPointF getSingleAdditionVector() const;
static sketcherMinimizerPointF
getSingleAdditionVector(const std::vector<sketcherMinimizerAtom*>& ats);
/* return true if the atom has valid 3d coordinates */
bool hasValid3DCoordinates() const;
/* return true if the atom is a residue */
virtual bool isResidue() const;
/* return true if atomicNumber represents a metal */
static bool isMetal(const unsigned int atomicNumber);
sketcherMinimizerAtomChiralityInfo m_chiralityInfo;
};
#endif // sketcherMINIMIZERATOM_H