Skip to content

Commit

Permalink
Better ringset prioritisation favouring heterocycles
Browse files Browse the repository at this point in the history
  • Loading branch information
johnmay committed Jun 26, 2016
1 parent 8675e1b commit 9401728
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 30 deletions.
65 changes: 65 additions & 0 deletions tool/sdg/src/main/java/org/openscience/cdk/layout/RingPlacer.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
import javax.vecmath.Tuple2d;
import javax.vecmath.Vector2d;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -792,4 +794,67 @@ public AtomPlacer getAtomPlacer() {
public void setAtomPlacer(AtomPlacer atomPlacer) {
this.atomPlacer = atomPlacer;
}


/**
* Sorts ring systems prioritising the most complex. To sort correctly,
* {@link #countHetero(List)} must first be invoked.
*/
static final Comparator<IRingSet> RING_COMPARATOR = new Comparator<IRingSet>() {
@Override
public int compare(IRingSet a, IRingSet b) {

// polycyclic better
int cmp = Boolean.compare(a.getAtomContainerCount() == 1, b.getAtomContainerCount() == 1);
if (cmp != 0) return cmp;

// more hetero atoms better
Integer numHeteroRingA = a.getProperty(NUM_HETERO_RINGS);
Integer numHeteroRingB = b.getProperty(NUM_HETERO_RINGS);
if (numHeteroRingA == null) numHeteroRingA = 0;
if (numHeteroRingB == null) numHeteroRingB = 0;
cmp = -Integer.compare(numHeteroRingA, numHeteroRingB);
if (cmp != 0) return cmp;

// more hetero rings better
Integer numHeteroAtomA = a.getProperty(NUM_HETERO_ATOMS);
Integer numHeteroAtomB = b.getProperty(NUM_HETERO_ATOMS);
if (numHeteroAtomA == null) numHeteroAtomA = 0;
if (numHeteroAtomB == null) numHeteroAtomB = 0;
cmp = -Integer.compare(numHeteroAtomA, numHeteroAtomB);
if (cmp != 0) return cmp;

// more rings better
return -Integer.compare(a.getAtomContainerCount(), b.getAtomContainerCount());
}
};

private static final String NUM_HETERO_RINGS = "sdg:numHeteroRings";
private static final String NUM_HETERO_ATOMS = "sdg:numHeteroAtoms";

/**
* Counds the number of hetero atoms and hetero rings in a ringset. The
* properties {@code sdg:numHeteroRings} and {@code sdg:numHeteroAtoms}
* are set.
*
* @param rsets ring systems
*/
static void countHetero(List<IRingSet> rsets) {
for (IRingSet rset : rsets) {
int numHeteroAtoms = 0;
int numHeteroRings = 0;
for (IAtomContainer ring : rset.atomContainers()) {
int prevNumHeteroAtoms = numHeteroAtoms;
for (IAtom atom : ring.atoms()) {
Integer elem = atom.getAtomicNumber();
if (elem != null && elem != 6 && elem != 1)
numHeteroAtoms++;
}
if (numHeteroAtoms > prevNumHeteroAtoms)
numHeteroRings++;
}
rset.setProperty(NUM_HETERO_ATOMS, numHeteroAtoms);
rset.setProperty(NUM_HETERO_RINGS, numHeteroRings);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -629,44 +629,34 @@ private void seedLayout() throws CDKException {
logger.debug("*** Start of handling rings. ***");
prepareRingSystems();

// We got our ring systems now, sort by number of bonds (largest first)
Collections.sort(ringSystems, new Comparator<IRingSet>() {
@Override
public int compare(IRingSet a, IRingSet b) {
return -Integer.compare(AtomContainerSetManipulator.getBondCount(a),
AtomContainerSetManipulator.getBondCount(b));
}
});

// Do the layout for the larges/most complex connected ring system
int largest = 0;
int numComplex = 0;
int largestSize = (ringSystems.get(0)).getAtomContainerCount();
if (largestSize > 1)
numComplex++;
logger.debug("We have " + ringSystems.size() + " ring system(s).");
for (int f = 1; f < ringSystems.size(); f++) {
logger.debug("RingSet " + f + " has size " + (ringSystems.get(f)).getAtomContainerCount());
int size = (ringSystems.get(f)).getAtomContainerCount();
if (size > 1)
numComplex++;
if (size > largestSize) {
largestSize = (ringSystems.get(f)).getAtomContainerCount();
largest = f;
// We got our ring systems now choose the best one based on size and
// number of heteroatoms
RingPlacer.countHetero(ringSystems);
Collections.sort(ringSystems, RingPlacer.RING_COMPARATOR);

int respect = layoutRingSet(firstBondVector, ringSystems.get(0));

// rotate monocyclic and when >= 4 polycyclic
if (respect == 1) {
if (ringSystems.get(0).getAtomContainerCount() == 1) {
respect = 0;
} else if (ringSystems.size() >= 4) {
int numPoly = 0;
for (IRingSet rset : ringSystems)
if (rset.getAtomContainerCount() > 1)
numPoly++;
if (numPoly >= 4)
respect = 0;
}
}
logger.debug("Largest RingSystem is at RingSet collection's position " + largest);
logger.debug("Size of Largest RingSystem: " + largestSize);

int respect = layoutRingSet(firstBondVector, ringSystems.get(largest));

if (respect == 1 && numComplex == 1 || respect == 2)
if (respect == 1 || respect == 2)
selectOrientation = false;

logger.debug("First RingSet placed");

// place of all the directly connected atoms of this ring system
ringPlacer.placeRingSubstituents(ringSystems.get(largest), bondLength);
ringPlacer.placeRingSubstituents(ringSystems.get(0), bondLength);
} else {

logger.debug("*** Start of handling purely aliphatic molecules. ***");
Expand Down

0 comments on commit 9401728

Please sign in to comment.