/* * sketcherMinimizerAtom.h * * Created by Nicola Zonta on 13/04/2010. * Copyright Schrodinger, LLC. All rights reserved. * */ #ifndef sketcherMINIMIZERATOM_H #define sketcherMINIMIZERATOM_H // #include #include "CoordgenConfig.hpp" #include "sketcherMinimizerMaths.h" #include #include #include 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> us, sketcherMinimizerAtom* dad, std::vector allPars, std::map* scors, std::map>* meds, std::map* 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* m) const; std::vector> theseAtoms; // NULL if dummy sketcherMinimizerAtom* parent; std::vector allParents; std::map* scores; std::map* visited; std::map>* 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 m_RSPriorities; int _implicitHs = -1; sketcherMinimizerMolecule* molecule; sketcherMinimizerFragment* fragment; void setFragment(sketcherMinimizerFragment* fragmentToSet) { fragment = fragmentToSet; } sketcherMinimizerFragment* getFragment() const { return fragment; } const std::vector& getBonds() const { return bonds; } const std::vector& 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 getSubmolecule(sketcherMinimizerAtom* excludedAtom); std::vector neighbors; std::vector bonds; std::vector residueInteractionPartners; std::vector residueInteractions; std::vector 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 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& v1, std::vector& v2); /* calculate CIP priorities and assign them */ static bool setCIPPriorities(std::vector& atomPriorities, sketcherMinimizerAtom* center); static void orderAtomPriorities( std::vector& 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 expandOneLevel(std::vector& 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& v); /* medals are used to mark parent atoms according to the priorities of their children and also their numbers. */ static void assignMedals(std::vector& 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& 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& 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