Skip to content

Commit

Permalink
Handle extended Cis/Trans when suppressing hydrogens.
Browse files Browse the repository at this point in the history
  • Loading branch information
johnmay committed May 3, 2018
1 parent 7c2e2ed commit 97b2e33
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -212,21 +212,23 @@ public List<IStereoElement> createAll() {
switch (centers.elementType(v)) {
// elongated tetrahedrals
case Bicoordinate:
int t0 = graph[v][0];
// end of an extended tetrahedral or cis/trans
if (centers.elementType(t0) == Stereocenters.Type.Tricoordinate) {
List<IBond> dbs = getCumulatedDbs(container.getBond(container.getAtom(t0),
container.getAtom(v)));
if (dbs.size() == 2) {
// extended tetrahedral
IStereoElement element = createExtendedTetrahedral(v, centers);
if (element != null) elements.add(element);
} else {
if (container.indexOf(dbs.get(0)) < container.indexOf(dbs.get(dbs.size()-1))) {
// extended cis-trans
IStereoElement element = createExtendedCisTrans(dbs);
for (int w : graph[v]) {
// end of an extended tetrahedral or cis/trans
if (centers.elementType(w) == Stereocenters.Type.Tricoordinate) {
List<IBond> dbs = getCumulatedDbs(container.getBond(container.getAtom(w),
container.getAtom(v)));
if (dbs.size() == 2) {
// extended tetrahedral
IStereoElement element = createExtendedTetrahedral(v, centers);
if (element != null) elements.add(element);
} else {
if (container.indexOf(dbs.get(0)) < container.indexOf(dbs.get(dbs.size() - 1))) {
// extended cis-trans
IStereoElement element = createExtendedCisTrans(dbs);
if (element != null) elements.add(element);
}
}
break;
}
}
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@
import org.openscience.cdk.ringsearch.RingSearch;
import org.openscience.cdk.sgroup.Sgroup;
import org.openscience.cdk.sgroup.SgroupKey;
import org.openscience.cdk.sgroup.SgroupType;
import org.openscience.cdk.stereo.Atropisomeric;
import org.openscience.cdk.stereo.DoubleBondStereochemistry;
import org.openscience.cdk.stereo.ExtendedCisTrans;
import org.openscience.cdk.stereo.ExtendedTetrahedral;
import org.openscience.cdk.stereo.TetrahedralChirality;

Expand Down Expand Up @@ -517,14 +517,15 @@ public static void convertImplicitToExplicitHydrogens(IAtomContainer atomContain

IAtom focus = tc.getFocus();
IAtom[] carriers = tc.getCarriers().toArray(new IAtom[4]);
IAtom hydrogen = hNeighbor.get(focus);

// in sulfoxide - the implicit part of the tetrahedral centre
// is a lone pair

if (hydrogen != null) {
replaceAtom(carriers, focus, hydrogen);
stereos.add(new TetrahedralChirality(focus, carriers, tc.getConfigOrder()));
IAtom[] ends = ExtendedTetrahedral.findTerminalAtoms(atomContainer, focus);
IAtom h1 = hNeighbor.get(ends[0]);
IAtom h2 = hNeighbor.get(ends[1]);
if (h1 != null || h2 != null) {
if (h1 != null)
replaceAtom(carriers, ends[0], h1);
if (h2 != null)
replaceAtom(carriers, ends[1], h2);
stereos.add(new ExtendedTetrahedral(focus, carriers, tc.getConfigOrder()));
} else {
stereos.add(stereo);
}
Expand Down Expand Up @@ -865,12 +866,12 @@ public static IAtomContainer suppressHydrogens(IAtomContainer org) {

if (hydrogens.contains(x)) {
conformation = conformation.invert();
xNew = findOther(org, u, v, x);
xNew = findSingleBond(org, u, x);
}

if (hydrogens.contains(y)) {
conformation = conformation.invert();
yNew = findOther(org, v, u, y);
yNew = findSingleBond(org, v, y);
}

// no other atoms connected, invalid double-bond configuration
Expand All @@ -891,6 +892,58 @@ public static IAtomContainer suppressHydrogens(IAtomContainer org) {
elements.add(new DoubleBondStereochemistry(orgStereo,
new IBond[]{cpyLeft, cpyRight},
conformation));
} else if (se instanceof ExtendedCisTrans) {
ExtendedCisTrans db = (ExtendedCisTrans) se;
int config = db.getConfigOrder();

IBond focus = db.getFocus();
IBond orgLeft = db.getCarriers().get(0);
IBond orgRight = db.getCarriers().get(1);

// we use the following variable names to refer to the
// extended double bond atoms and substituents
// x y
// \ /
// u===v
IAtom[] ends = ExtendedCisTrans.findTerminalAtoms(org, focus);
IAtom u = ends[0];
IAtom v = ends[1];
IAtom x = orgLeft.getOther(u);
IAtom y = orgRight.getOther(v);

// if xNew == x and yNew == y we don't need to find the
// connecting bonds
IAtom xNew = x;
IAtom yNew = y;

if (hydrogens.contains(x)) {
config ^= 0x3;
xNew = findSingleBond(org, u, x);
}

if (hydrogens.contains(y)) {
config ^= 0x3;
yNew = findSingleBond(org, v, y);
}

// no other atoms connected, invalid double-bond configuration
// is removed. example [2H]/C=C/[H]
if (x == null || y == null ||
xNew == null || yNew == null) continue;

// no changes
if (x.equals(xNew) && y.equals(yNew)) {
elements.add(db);
continue;
}

// XXX: may perform slow operations but works for now
IBond cpyLeft = !Objects.equals(xNew, x) ? org.getBond(u, xNew) : orgLeft;
IBond cpyRight = !Objects.equals(yNew, y) ? org.getBond(v, yNew) : orgRight;

elements.add(new ExtendedCisTrans(focus,
new IBond[]{cpyLeft, cpyRight},
config));
} else if (se instanceof Atropisomeric) {
// can not have any H's
elements.add(se);
Expand Down Expand Up @@ -1039,18 +1092,21 @@ private static boolean suppressibleHydrogen(final IAtomContainer container, fina
}

/**
* Finds an neighbor connected to 'atom' which is not 'exclude1'
* or 'exclude2'. If no neighbor exists - null is returned.
* Finds an neighbor connected to 'atom' which is connected by a
* single bond and is not 'exclude'.
*
* @param container structure
* @param atom atom to find a neighbor of
* @param exclude1 the neighbor should not be this atom
* @param exclude2 the neighbor should also not be this atom
* @param exclude the neighbor should not be this atom
* @return a neighbor of 'atom', null if not found
*/
private static IAtom findOther(IAtomContainer container, IAtom atom, IAtom exclude1, IAtom exclude2) {
for (IAtom neighbor : container.getConnectedAtomsList(atom)) {
if (!neighbor.equals(exclude1) && !neighbor.equals(exclude2)) return neighbor;
private static IAtom findSingleBond(IAtomContainer container, IAtom atom, IAtom exclude) {
for (IBond bond : container.getConnectedBondsList(atom)) {
if (bond.getOrder() != Order.SINGLE)
continue;
IAtom neighbor = bond.getOther(atom);
if (!neighbor.equals(exclude))
return neighbor;
}
return null;
}
Expand Down

0 comments on commit 97b2e33

Please sign in to comment.