if (haveAtomStereochemistry) {
if (Logger.debugging)
Logger.debug("checking stereochemistry...");
JmolNode atom1 = null, atom2 = null, atom3 = null, atom4 = null, atom5 = null, atom6 = null;
SmilesAtom sAtom1 = null, sAtom2 = null;
JmolNode[] jn;
for (int i = 0; i < atomCount; i++) {
SmilesAtom sAtom = patternAtoms[i];
JmolNode atom0 = jmolAtoms[sAtom.getMatchingAtom()];
int nH = sAtom.missingHydrogenCount;
if (nH < 0)
nH = 0;
int chiralClass = sAtom.getChiralClass();
if (chiralClass == Integer.MIN_VALUE)
continue;
int order = sAtom.getChiralOrder();
if (isSmilesFind && (atom0.getAtomSite() >> 8) != chiralClass)
return false;
atom4 = null;
if (Logger.debugging)
Logger.debug("...type " + chiralClass);
switch (chiralClass) {
// case SmilesAtom.STEREOCHEMISTRY_DOUBLE_BOND:
case SmilesAtom.STEREOCHEMISTRY_ALLENE:
boolean isAllene = true;//(chiralClass == SmilesAtom.STEREOCHEMISTRY_ALLENE);
if (isAllene) {
sAtom1 = sAtom.getBond(0).getOtherAtom(sAtom);
sAtom2 = sAtom.getBond(1).getOtherAtom(sAtom);
if (sAtom1 == null || sAtom2 == null)
continue; // "OK - stereochemistry is desgnated for something like C=C=O
// cumulenes
SmilesAtom sAtom1a = sAtom;
SmilesAtom sAtom2a = sAtom;
while (sAtom1.getBondCount() == 2
&& sAtom2.getBondCount() == 2
&& sAtom1.getValence() == 4 && sAtom2.getValence() == 4) {
SmilesBond b = sAtom1.getBondNotTo(sAtom1a, true);
sAtom1a = sAtom1;
sAtom1 = b.getOtherAtom(sAtom1);
b = sAtom2.getBondNotTo(sAtom2a, true);
sAtom2a = sAtom2;
sAtom2 = b.getOtherAtom(sAtom2);
}
sAtom = sAtom1;
}
jn = new JmolNode[6];
jn[4] = new SmilesAtom(604);
int nBonds = sAtom.getBondCount();
for (int k = 0; k < nBonds; k++) {
sAtom1 = sAtom.bonds[k].getOtherAtom(sAtom);
if (sAtom.bonds[k].matchingBond.getCovalentOrder() == 2) {
if (sAtom2 == null)
sAtom2 = sAtom1;
} else if (jn[0] == null) {
jn[0] = getJmolAtom(sAtom1.getMatchingAtom());
} else {
jn[1] = getJmolAtom(sAtom1.getMatchingAtom());
}
}
if (sAtom2 == null)
continue;
nBonds = sAtom2.getBondCount();
if (nBonds < 2 || nBonds > 3)
continue; // [C@]=O always matches
for (int k = 0; k < nBonds; k++) {
sAtom1 = sAtom2.bonds[k].getOtherAtom(sAtom2);
if (sAtom2.bonds[k].matchingBond.getCovalentOrder() == 2) {
} else if (jn[2] == null) {
jn[2] = getJmolAtom(sAtom1.getMatchingAtom());
} else {
jn[3] = getJmolAtom(sAtom1.getMatchingAtom());
}
}
if (isSmilesFind) {
if (jn[1] == null)
getX(sAtom, sAtom2, jn, 1, false, isAllene);
if (jn[3] == null)
getX(sAtom2, sAtom, jn, 3, false, false);
if (!setSmilesCoordinates(atom0, sAtom, sAtom2, jn))
return false;
}
if (jn[1] == null)
getX(sAtom, sAtom2, jn, 1, true, false);
if (jn[3] == null)
getX(sAtom2, sAtom, jn, 3, true, false);
if (!checkStereochemistry(sAtom.not, atom0, chiralClass, order,
jn[0], jn[1], jn[2], jn[3], null, null, v))
return false;
continue;
case SmilesAtom.STEREOCHEMISTRY_TETRAHEDRAL:
case SmilesAtom.STEREOCHEMISTRY_SQUARE_PLANAR:
case SmilesAtom.STEREOCHEMISTRY_TRIGONAL_BIPYRAMIDAL:
case SmilesAtom.STEREOCHEMISTRY_OCTAHEDRAL:
atom1 = getJmolAtom(sAtom.getMatchingBondedAtom(0));
switch (nH) {
case 0:
atom2 = getJmolAtom(sAtom.getMatchingBondedAtom(1));
break;
case 1:
atom2 = getHydrogens(getJmolAtom(sAtom.getMatchingAtom()), null);
if (sAtom.isFirst) {
JmolNode a = atom2;
atom2 = atom1;
atom1 = a;
}
break;
default:
continue;
}
atom3 = getJmolAtom(sAtom.getMatchingBondedAtom(2 - nH));
atom4 = getJmolAtom(sAtom.getMatchingBondedAtom(3 - nH));
atom5 = getJmolAtom(sAtom.getMatchingBondedAtom(4 - nH));
atom6 = getJmolAtom(sAtom.getMatchingBondedAtom(5 - nH));
// in all the checks below, we use Measure utilities to
// three given atoms -- the normal, in particular. We
// then use dot products to check the directions of normals
// to see if the rotation is in the direction required.
// we only use TP1, TP2, OH1, OH2 here.
// so we must also check that the two bookend atoms are axial
if (isSmilesFind
&& !setSmilesCoordinates(atom0, sAtom, sAtom2, new JmolNode[] {
atom1, atom2, atom3, atom4, atom5, atom6 }))
return false;
if (!checkStereochemistry(sAtom.not, atom0, chiralClass, order,
atom1, atom2, atom3, atom4, atom5, atom6, v))
return false;
continue;
}
}
}
// next, /C=C/ double bond stereochemistry
if (haveBondStereochemistry) {
for (int k = 0; k < atomCount; k++) {
SmilesAtom sAtom1 = patternAtoms[k];
SmilesAtom sAtom2 = null;
SmilesAtom sAtomDirected1 = null;
SmilesAtom sAtomDirected2 = null;
int dir1 = 0;
int dir2 = 0;
int bondType = 0;
SmilesBond b;
int nBonds = sAtom1.getBondCount();
boolean isAtropisomer = false;
for (int j = 0; j < nBonds; j++) {
b = sAtom1.getBond(j);
boolean isAtom2 = (b.getAtom2() == sAtom1);
int type = b.bondType;
switch (type) {
case SmilesBond.TYPE_ATROPISOMER_1:
case SmilesBond.TYPE_ATROPISOMER_2:
case SmilesBond.TYPE_DOUBLE:
if (isAtom2)
continue;
sAtom2 = b.getAtom2();
bondType = type;
isAtropisomer = (type != SmilesBond.TYPE_DOUBLE);
if (isAtropisomer)
dir1 = (b.isNot ? -1 : 1);
break;
case SmilesBond.TYPE_DIRECTIONAL_1:
case SmilesBond.TYPE_DIRECTIONAL_2:
sAtomDirected1 = (isAtom2 ? b.getAtom1() : b.getAtom2());
dir1 = (isAtom2 != (type == SmilesBond.TYPE_DIRECTIONAL_1) ? 1 : -1);
break;
}
}
if (isAtropisomer) {
//System.out.println(sAtom1 + " " + sAtom2);
b = sAtom1.getBondNotTo(sAtom2, false);
if (b == null)
return false;
sAtomDirected1 = b.getOtherAtom(sAtom1);
b = sAtom2.getBondNotTo(sAtom1, false);
if (b == null)
return false;
sAtomDirected2 = b.getOtherAtom(sAtom2);
} else {
if (sAtom2 == null || dir1 == 0)
continue;
nBonds = sAtom2.getBondCount();
for (int j = 0; j < nBonds && dir2 == 0; j++) {
b = sAtom2.getBond(j);
boolean isAtom2 = (b.getAtom2() == sAtom2);
int type = b.bondType;
switch (type) {
case SmilesBond.TYPE_DIRECTIONAL_1:
case SmilesBond.TYPE_DIRECTIONAL_2:
sAtomDirected2 = (isAtom2 ? b.getAtom1() : b.getAtom2());
dir2 = (isAtom2 != (type == SmilesBond.TYPE_DIRECTIONAL_1) ? 1
: -1);
break;
}
}
if (dir2 == 0)
continue;
}
if (isSmilesFind)
setSmilesBondCoordinates(sAtom1, sAtom2, bondType);
JmolNode dbAtom1 = getJmolAtom(sAtom1.getMatchingAtom());
JmolNode dbAtom2 = getJmolAtom(sAtom2.getMatchingAtom());
JmolNode dbAtom1a = getJmolAtom(sAtomDirected1.getMatchingAtom());
JmolNode dbAtom2a = getJmolAtom(sAtomDirected2.getMatchingAtom());
if (dbAtom1a == null || dbAtom2a == null)
return false;
SmilesMeasure.setTorsionData((Point3f) dbAtom1a, (Point3f) dbAtom1,
(Point3f) dbAtom2, (Point3f) dbAtom2a, v, isAtropisomer);
if (isAtropisomer) {