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
|
/*
Contributors: Nicola Zonta
Copyright Schrodinger, LLC. All rights reserved
*/
#ifndef COORDGEN_FRAGMENT_BUILDER_H
#define COORDGEN_FRAGMENT_BUILDER_H
#include <queue>
#include <set>
#include <stack>
#include <vector>
#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<sketcherMinimizerAtom*>
orderRingAtoms(const sketcherMinimizerRing* r);
/*
return a vector of atoms so that bound atoms are placed next to each other
*/
static std::vector<sketcherMinimizerAtom*>
orderChainOfAtoms(const std::vector<sketcherMinimizerAtom*>& atoms,
sketcherMinimizerAtom* startAtom);
/*
return a list of coordinates representing a regular polygon for the given
atoms in a ring
*/
static std::vector<sketcherMinimizerPointF>
listOfCoordinatesFromListofRingAtoms(
const std::vector<sketcherMinimizerAtom*>& 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<sketcherMinimizerAtom*>& 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<sketcherMinimizerRing*> centralRings) const;
sketcherMinimizerRing* findCentralRingOfSystem(
const std::vector<sketcherMinimizerRing*>& rings) const;
/*
find a template to generate coordinates for a ring system
*/
bool findTemplate(const std::vector<sketcherMinimizerRing*>& rings) const;
/*
generate coordinates for rings that have been stripped away from the core
(see buildRings)
*/
void generateCoordinatesSideRings(
std::stack<sketcherMinimizerRing*> 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<sketcherMinimizerRing*>& allRings,
std::stack<sketcherMinimizerRing*>& sideRings,
std::vector<sketcherMinimizerRing*>& 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<sketcherMinimizerAtom*>& atomQueue,
std::set<sketcherMinimizerAtom*>& isAtomVisited,
const sketcherMinimizerFragment* fragment) const;
/* return a list of angles that bonds from the given atoms should form */
std::vector<float>
neighborsAnglesAtCenter(const sketcherMinimizerAtom* atom) const;
/* initialize data to generate coordinates of atoms bound to a non-ring atom
*/
void initializeVariablesForNeighboursCoordinates(
sketcherMinimizerAtom* atom,
std::set<sketcherMinimizerAtom*>& isAtomVisited,
sketcherMinimizerPointF& startCoordinates,
std::vector<sketcherMinimizerAtom*>& orderedNeighbors,
std::vector<float>& angles) const;
/* initialize data to generate coordinates of atoms bound to a ring atom */
void initializeVariablesForNeighboursCoordinatesRingAtom(
const sketcherMinimizerAtom* atom,
std::set<sketcherMinimizerAtom*>& isAtomVisited,
sketcherMinimizerPointF& startCoordinates,
std::vector<sketcherMinimizerAtom*>& orderedNeighbors,
std::vector<float>& 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<sketcherMinimizerAtom*>& isAtomVisited) const;
/* assign a score to the possibility of rings to be drawn on a plane */
float
newScorePlanarity(const std::vector<sketcherMinimizerRing*>& rings) const;
/* the macrocycle builder */
CoordgenMacrocycleBuilder m_macrocycleBuilder;
};
#endif /* defined(COORDGEN_FRAGMENT_BUILDER_H) */
|