/* Contributors: Nicola Zonta Copyright Schrodinger, LLC. All rights reserved */ #ifndef COORDGEN_FRAGMENT_BUILDER_H #define COORDGEN_FRAGMENT_BUILDER_H #include #include #include #include #include "CoordgenConfig.hpp" #include "CoordgenMacrocycleBuilder.h" class sketcherMinimizerAtom; class sketcherMinimizerBond; class sketcherMinimizerRing; class sketcherMinimizerFragment; class sketcherMinimizerPointF; /* class that handles the creation of 2d coordinates for a molecular fragment */ class EXPORT_COORDGEN CoordgenFragmentBuilder { public: /* create coordinates for a molecular fragment */ void initializeCoordinates(sketcherMinimizerFragment* fragment) const; /* return a vector of ring atoms so that bound atoms are placed next to each other */ static std::vector orderRingAtoms(const sketcherMinimizerRing* r); /* return a vector of atoms so that bound atoms are placed next to each other */ static std::vector orderChainOfAtoms(const std::vector& atoms, sketcherMinimizerAtom* startAtom); /* return a list of coordinates representing a regular polygon for the given atoms in a ring */ static std::vector listOfCoordinatesFromListofRingAtoms( const std::vector& atoms); /* set a flag that forces the macrocycle builder to skip expensive polyomino matching routines and go straight to the breaking a bond approach */ void setForceOpenMacrocycles(bool b) { m_macrocycleBuilder.m_forceOpenMacrocycles = b; } /* set precision of the calculations. Higher precisions settings result better quality but slower calculations */ void setPrecision(float f) { m_macrocycleBuilder.setPrecision(f); } /* all bonds are placed at even intervals around the atom, as opposed for instance to the 90°-90°-120°-60° around tetracoordinated centers */ bool m_evenAngles; private: /* find if the present ring is fused with another than has already gotten coordinates for */ sketcherMinimizerRing* getSharedAtomsWithAlreadyDrawnRing( const sketcherMinimizerRing* ring, std::vector& fusionAtoms, sketcherMinimizerBond*& fusionBond) const; /* assign coordinates to a ring */ void buildRing(sketcherMinimizerRing* ring) const; /* generate coordinates for a group of fused rings that share more than two atoms with each other */ void generateCoordinatesCentralRings( std::vector centralRings) const; sketcherMinimizerRing* findCentralRingOfSystem( const std::vector& rings) const; /* find a template to generate coordinates for a ring system */ bool findTemplate(const std::vector& rings) const; /* generate coordinates for rings that have been stripped away from the core (see buildRings) */ void generateCoordinatesSideRings( std::stack sideRings) const; /* after coordinates are generated, find an orientation for the main fragment */ void rotateMainFragment(sketcherMinimizerFragment* fragment) const; /* assign coordinates to a fragment */ void buildFragment(sketcherMinimizerFragment* fragment) const; /* assign coordinates to all ring atoms. Start by stripping out side rings that only share two atoms with other rings to find a core of central rings */ void buildRings(sketcherMinimizerFragment* fragment) const; /* assign coordinates to atoms that are not in rings */ void buildNonRingAtoms(sketcherMinimizerFragment* fragment) const; /* initialize information about connectivity of rings */ void initializeFusedRingInformation(sketcherMinimizerFragment* fragment) const; /* split ring system into side rings and central rings by stripping away recursively rings that only share two atoms with other rings */ void simplifyRingSystem(const std::vector& allRings, std::stack& sideRings, std::vector& centralRings) const; /* if the fragment contains any NaN coordinates and 3d coords are available, * use thouse instead */ void fallbackIfNanCoordinates(sketcherMinimizerFragment* fragment) const; /* generate the coordinates of atoms bound to the first atom in the queue */ void generateCoordinatesNeighborsOfFirstAtomInQueue( std::queue& atomQueue, std::set& isAtomVisited, const sketcherMinimizerFragment* fragment) const; /* return a list of angles that bonds from the given atoms should form */ std::vector neighborsAnglesAtCenter(const sketcherMinimizerAtom* atom) const; /* initialize data to generate coordinates of atoms bound to a non-ring atom */ void initializeVariablesForNeighboursCoordinates( sketcherMinimizerAtom* atom, std::set& isAtomVisited, sketcherMinimizerPointF& startCoordinates, std::vector& orderedNeighbours, std::vector& angles) const; /* initialize data to generate coordinates of atoms bound to a ring atom */ void initializeVariablesForNeighboursCoordinatesRingAtom( const sketcherMinimizerAtom* atom, std::set& isAtomVisited, sketcherMinimizerPointF& startCoordinates, std::vector& orderedNeighbours, std::vector& angles) const; /* check if the atom is part of a macrocycle and has some degrees of freedom that can be added to be used in the minimizer */ void maybeAddMacrocycleDOF(sketcherMinimizerAtom* atom) const; /* make sure ZE chirality is maintained */ void avoidZEInversions(const sketcherMinimizerAtom* at, std::set& isAtomVisited) const; /* assign a score to the possibility of rings to be drawn on a plane */ float newScorePlanarity(const std::vector& rings) const; /* the macrocycle builder */ CoordgenMacrocycleBuilder m_macrocycleBuilder; }; #endif /* defined(COORDGEN_FRAGMENT_BUILDER_H) */