1 /* 2 * sketcherMinimizerAtom.h 3 * 4 * Created by Nicola Zonta on 13/04/2010. 5 * Copyright Schrodinger, LLC. All rights reserved. 6 * 7 */ 8 9 #ifndef sketcherMINIMIZERATOM_H 10 #define sketcherMINIMIZERATOM_H 11 12 // #include <sketcherMinimizerPointF> 13 #include "CoordgenConfig.hpp" 14 #include "sketcherMinimizerMaths.h" 15 #include <iostream> 16 #include <map> 17 #include <vector> 18 19 static const int COORDINATES_LIMIT = 10000000; 20 static const int INVALID_COORDINATES = COORDINATES_LIMIT + 1; 21 22 class sketcherMinimizerBond; 23 24 class sketcherMinimizerFragment; 25 class sketcherMinimizerRing; 26 class sketcherMinimizerMolecule; 27 28 class sketcherMinimizerAtom; 29 typedef struct { 30 sketcherMinimizerAtom* a; 31 unsigned int priority; 32 } sketcherMinimizerAtomPriority; 33 34 struct sketcherMinimizerAtomChiralityInfo { 35 enum sketcherMinimizerChirality { 36 clockwise, 37 counterClockwise, 38 unspecified 39 }; 40 41 sketcherMinimizerAtom* lookingFrom = nullptr; 42 sketcherMinimizerAtom* atom1 = nullptr; 43 sketcherMinimizerAtom* atom2 = nullptr; 44 sketcherMinimizerChirality direction = unspecified; 45 }; 46 47 /* structure to represent an atom in Cahn–Ingold–Prelog priorities assignment */ 48 struct CIPAtom { CIPAtomCIPAtom49 CIPAtom(std::vector<std::pair<int, sketcherMinimizerAtom*>> us, 50 sketcherMinimizerAtom* dad, 51 std::vector<sketcherMinimizerAtom*> allPars, 52 std::map<sketcherMinimizerAtom*, int>* scors, 53 std::map<sketcherMinimizerAtom*, std::vector<int>>* meds, 54 std::map<sketcherMinimizerAtom*, int>* visits 55 56 ) 57 : theseAtoms(std::move(us)), parent(dad), 58 allParents(std::move(allPars)), scores(scors), visited(visits), 59 medals(meds) 60 { 61 } 62 bool operator<(const CIPAtom& rhs) const; 63 bool operator==(const CIPAtom& rhs) const; 64 bool isBetter(CIPAtom& rhs, 65 std::map<sketcherMinimizerAtom*, unsigned int>* m) const; 66 67 std::vector<std::pair<int, sketcherMinimizerAtom*>> 68 theseAtoms; // NULL if dummy 69 sketcherMinimizerAtom* parent; 70 std::vector<sketcherMinimizerAtom*> allParents; 71 std::map<sketcherMinimizerAtom*, int>* scores; 72 std::map<sketcherMinimizerAtom*, int>* visited; 73 std::map<sketcherMinimizerAtom*, std::vector<int>>* medals; 74 75 private: 76 friend std::ostream& operator<<(std::ostream& os, const CIPAtom& a); 77 }; 78 79 /* class to represent an atom */ 80 class EXPORT_COORDGEN sketcherMinimizerAtom 81 { 82 public: 83 sketcherMinimizerAtom(); 84 virtual ~sketcherMinimizerAtom(); 85 86 bool crossLayout; // atoms with 4 substituents displayed in a cross style 87 // (such as S in sulphate) 88 bool fixed, constrained, rigid; 89 bool isSharedAndInner; // shared by two rings and needs to be drawn inside a 90 // ring 91 bool hidden; 92 int atomicNumber, charge, _valence, _generalUseN, _generalUseN2; 93 int m_chmN; // idx of the corresponding ChmAtom if molecule comes from 3d 94 95 bool _generalUseVisited, _generalUseVisited2; 96 bool m_clockwiseInvert; 97 bool m_ignoreRingChirality; 98 std::vector<int> m_RSPriorities; 99 int _implicitHs = -1; 100 sketcherMinimizerMolecule* molecule; 101 sketcherMinimizerFragment* fragment; setFragment(sketcherMinimizerFragment * fragmentToSet)102 void setFragment(sketcherMinimizerFragment* fragmentToSet) 103 { 104 fragment = fragmentToSet; 105 } getFragment()106 sketcherMinimizerFragment* getFragment() const { return fragment; } getBonds()107 const std::vector<sketcherMinimizerBond*>& getBonds() const 108 { 109 return bonds; 110 } getRings()111 const std::vector<sketcherMinimizerRing*>& getRings() const 112 { 113 return rings; 114 } 115 getMolecule()116 sketcherMinimizerMolecule* getMolecule() const { return molecule; } 117 118 /* 119 Find all connected atoms, pruning the search at the excludedAtom." 120 This function assumes that the bond between this atom and excludedAtom 121 is not part of a ring. 122 */ 123 std::vector<sketcherMinimizerAtom*> 124 getSubmolecule(sketcherMinimizerAtom* excludedAtom); 125 std::vector<sketcherMinimizerAtom*> neighbors; 126 std::vector<sketcherMinimizerBond*> bonds; 127 std::vector<sketcherMinimizerAtom*> residueInteractionPartners; 128 std::vector<sketcherMinimizerBond*> residueInteractions; 129 std::vector<sketcherMinimizerRing*> rings; 130 float m_pseudoZ; 131 132 float m_x3D; 133 float m_y3D; 134 float m_z3D; 135 136 bool m_isClashing, m_isWaterMap; 137 float m_pocketDistance; 138 139 bool needsCheckForClashes; 140 bool m_isLigand; 141 bool visited, coordinatesSet; 142 bool isR; // stereochemistry 143 bool hasStereochemistrySet, m_isStereogenic; 144 bool _hasRingChirality; // used to keep track of cyclohexane cis/trans 145 // chirality 146 147 /* write coordinates to atom */ 148 void setCoordinates(sketcherMinimizerPointF coords); 149 150 /* check that the atom has no double bonds possibly involved in E/Z 151 * stereochemistry */ 152 bool hasNoStereoActiveBonds() const; 153 getCoordinates()154 const sketcherMinimizerPointF& getCoordinates() const 155 { 156 return coordinates; 157 } getAtomicNumber()158 int getAtomicNumber() const { return atomicNumber; } 159 setAtomicNumber(int number)160 void setAtomicNumber(int number) { atomicNumber = number; } 161 setStereoChemistry(sketcherMinimizerAtomChiralityInfo info)162 void setStereoChemistry(sketcherMinimizerAtomChiralityInfo info) 163 { 164 m_chiralityInfo = info; 165 } 166 167 /* write template coordinates to atom */ setCoordinatesToTemplate()168 void setCoordinatesToTemplate() { setCoordinates(templateCoordinates); } 169 sketcherMinimizerPointF coordinates; 170 sketcherMinimizerPointF templateCoordinates; 171 sketcherMinimizerPointF force; 172 173 /* return the expected valence for the atom */ 174 unsigned int expectedValence(unsigned int atomicNumber) const; 175 176 bool canBeChiral() const; // checks if the atom can have 4 substituents (one 177 // can be implicit H). Doesn't actually check if 178 // two of them are the same, so can return true 179 // for achiral centers 180 181 /* return true if this and at2 share a bond */ isNeighborOf(sketcherMinimizerAtom * at2)182 bool isNeighborOf(sketcherMinimizerAtom* at2) const 183 { 184 for (auto& neighbor : at2->neighbors) { 185 if (neighbor == this) { 186 return true; 187 } 188 } 189 return false; 190 } 191 192 sketcherMinimizerAtomChiralityInfo::sketcherMinimizerChirality 193 getRelativeStereo(sketcherMinimizerAtom* lookingFrom, 194 sketcherMinimizerAtom* atom1, 195 sketcherMinimizerAtom* atom2); 196 bool setAbsoluteStereoFromChiralityInfo(); 197 198 /* if this atom and the given one share a bond, return it */ 199 sketcherMinimizerBond* bondTo(sketcherMinimizerAtom* at) const; 200 201 /* return all bonded atoms, ordered as they appear clockwise around this */ 202 std::vector<sketcherMinimizerAtom*> clockwiseOrderedNeighbors() const; 203 int findHsNumber() const; 204 205 void writeStereoChemistry(); // assigns up-down bond flags based on isR and 206 // hasStereochemistrySet 207 208 /* return true if the two sequences represent the same isomer */ 209 static bool matchCIPSequence(std::vector<int>& v1, std::vector<int>& v2); 210 211 /* calculate CIP priorities and assign them */ 212 static bool 213 setCIPPriorities(std::vector<sketcherMinimizerAtomPriority>& atomPriorities, 214 sketcherMinimizerAtom* center); 215 216 static void orderAtomPriorities( 217 std::vector<sketcherMinimizerAtomPriority>& atomPriorities, 218 sketcherMinimizerAtom* center); // orders trying to keep long chains in 219 // position 2 and 3 and side 220 // substituents in 1 and 4 221 222 /* return which between at1 and at2 has higher CIP priority. Returns NULL if 223 * they have the same */ 224 static sketcherMinimizerAtom* CIPPriority(sketcherMinimizerAtom* at1, 225 sketcherMinimizerAtom* at2, 226 sketcherMinimizerAtom* center); 227 228 /* consider one additional level of bound atoms in the CIP algorithm to 229 * break a tie */ 230 static std::vector<CIPAtom> expandOneLevel(std::vector<CIPAtom>& oldV); 231 232 /* if any ties between parent atoms was solved, assign two different scores 233 to them. Also clear the medals for the next iteration */ 234 static void finalizeScores(std::vector<CIPAtom>& v); 235 236 /* medals are used to mark parent atoms according to the priorities of their 237 children and also their numbers. */ 238 static void assignMedals(std::vector<CIPAtom>& v); 239 240 /* first atom will be the highest priority, subsequent will be based on 241 * atoms that have already been picked, giving priorities to branches that 242 * have been already been visited. friendsMask keeps track of parents that 243 * have a child that has been already selected */ 244 static void chooseFirstAndSortAccordingly(std::vector<CIPAtom>& V); 245 246 /* if the two atoms share a ring, return it */ 247 static sketcherMinimizerRing* 248 shareARing(const sketcherMinimizerAtom* atom1, 249 const sketcherMinimizerAtom* atom2); 250 251 /* mirror the coordinates of at wrt bond */ 252 static void mirrorCoordinates(sketcherMinimizerAtom* at, 253 const sketcherMinimizerBond* bond); 254 255 /* return the stereochemistry set in the wedges around the atom. 0 if not 256 * assigned, 1 if R, -1 if S */ 257 int readStereochemistry(bool readOnly = false); 258 259 /* return a direction perpendicular to the atom's bonds average */ 260 sketcherMinimizerPointF getSingleAdditionVector() const; 261 262 static sketcherMinimizerPointF 263 getSingleAdditionVector(const std::vector<sketcherMinimizerAtom*>& ats); 264 265 /* return true if the atom has valid 3d coordinates */ 266 bool hasValid3DCoordinates() const; 267 268 /* return true if the atom is a residue */ 269 virtual bool isResidue() const; 270 271 /* return true if atomicNumber represents a metal */ 272 static bool isMetal(const unsigned int atomicNumber); 273 274 sketcherMinimizerAtomChiralityInfo m_chiralityInfo; 275 }; 276 277 #endif // sketcherMINIMIZERATOM_H 278