use of org.openscience.cdk.interfaces.ITetrahedralChirality.Stereo in project cdk by cdk.
the class InChIGeneratorTest method r_penta_2_3_diene_impl_h.
@Test
public void r_penta_2_3_diene_impl_h() throws Exception {
IAtomContainer m = new AtomContainer(5, 4, 0, 0);
m.addAtom(new Atom("CH3"));
m.addAtom(new Atom("CH"));
m.addAtom(new Atom("C"));
m.addAtom(new Atom("CH"));
m.addAtom(new Atom("CH3"));
m.addBond(0, 1, IBond.Order.SINGLE);
m.addBond(1, 2, IBond.Order.DOUBLE);
m.addBond(2, 3, IBond.Order.DOUBLE);
m.addBond(3, 4, IBond.Order.SINGLE);
int[][] atoms = new int[][] { { 0, 1, 3, 4 }, { 1, 0, 3, 4 }, { 1, 0, 4, 3 }, { 0, 1, 4, 3 }, { 4, 3, 1, 0 }, { 4, 3, 0, 1 }, { 3, 4, 0, 1 }, { 3, 4, 1, 0 } };
Stereo[] stereos = new Stereo[] { Stereo.ANTI_CLOCKWISE, Stereo.CLOCKWISE, Stereo.ANTI_CLOCKWISE, Stereo.CLOCKWISE, Stereo.ANTI_CLOCKWISE, Stereo.CLOCKWISE, Stereo.ANTI_CLOCKWISE, Stereo.CLOCKWISE };
for (int i = 0; i < atoms.length; i++) {
IStereoElement element = new ExtendedTetrahedral(m.getAtom(2), new IAtom[] { m.getAtom(atoms[i][0]), m.getAtom(atoms[i][1]), m.getAtom(atoms[i][2]), m.getAtom(atoms[i][3]) }, stereos[i]);
m.setStereoElements(Collections.singletonList(element));
InChIGenerator generator = getFactory().getInChIGenerator(m);
assertThat(generator.getInchi(), is("InChI=1S/C5H8/c1-3-5-4-2/h3-4H,1-2H3/t5-/m0/s1"));
}
}
use of org.openscience.cdk.interfaces.ITetrahedralChirality.Stereo in project cdk by cdk.
the class CDKToBeamTest method r_penta_2_3_diene_expl_h.
@Test
public void r_penta_2_3_diene_expl_h() throws Exception {
IAtomContainer m = new AtomContainer(5, 4, 0, 0);
m.addAtom(new Atom("C"));
m.addAtom(new Atom("C"));
m.addAtom(new Atom("C"));
m.addAtom(new Atom("C"));
m.addAtom(new Atom("C"));
m.addAtom(new Atom("H"));
m.addAtom(new Atom("H"));
m.addBond(0, 1, IBond.Order.SINGLE);
m.addBond(1, 2, IBond.Order.DOUBLE);
m.addBond(2, 3, IBond.Order.DOUBLE);
m.addBond(3, 4, IBond.Order.SINGLE);
m.addBond(1, 5, IBond.Order.SINGLE);
m.addBond(3, 6, IBond.Order.SINGLE);
int[][] atoms = new int[][] { { 0, 5, 6, 4 }, { 5, 0, 6, 4 }, { 5, 0, 4, 6 }, { 0, 5, 4, 6 }, { 4, 6, 5, 0 }, { 4, 6, 0, 5 }, { 6, 4, 0, 5 }, { 6, 4, 5, 0 } };
Stereo[] stereos = new Stereo[] { Stereo.ANTI_CLOCKWISE, Stereo.CLOCKWISE, Stereo.ANTI_CLOCKWISE, Stereo.CLOCKWISE, Stereo.ANTI_CLOCKWISE, Stereo.CLOCKWISE, Stereo.ANTI_CLOCKWISE, Stereo.CLOCKWISE };
for (int i = 0; i < atoms.length; i++) {
IStereoElement element = new ExtendedTetrahedral(m.getAtom(2), new IAtom[] { m.getAtom(atoms[i][0]), m.getAtom(atoms[i][1]), m.getAtom(atoms[i][2]), m.getAtom(atoms[i][3]) }, stereos[i]);
m.setStereoElements(Collections.singletonList(element));
assertThat(convert(m, SmiFlavor.Stereo).toSmiles(), is("CC(=[C@@]=C(C)[H])[H]"));
}
}
use of org.openscience.cdk.interfaces.ITetrahedralChirality.Stereo in project cdk by cdk.
the class MDLV2000Reader method createStereo0d.
static IStereoElement<IAtom, IAtom> createStereo0d(IAtomContainer mol, IAtom focus, int parity) {
if (parity != 1 && parity != 2)
// 3=unspec
return null;
int numNbrs = 0;
IAtom[] carriers = new IAtom[4];
int idxOfHyd = -1;
for (IAtom nbr : mol.getConnectedAtomsList(focus)) {
if (numNbrs == 4)
// too many neighbors
return null;
if (nbr.getAtomicNumber() == IElement.H) {
if (idxOfHyd >= 0)
// too many hydrogens
return null;
idxOfHyd = numNbrs;
}
carriers[numNbrs++] = nbr;
}
// incorrect number of neighbours?
if (numNbrs < 3 || numNbrs < 4 && idxOfHyd >= 0)
return null;
// implicit neighbour (H or lone-pair)
if (numNbrs == 3)
carriers[numNbrs++] = focus;
if (numNbrs != 4)
return null;
Stereo winding = parity == 1 ? Stereo.CLOCKWISE : Stereo.ANTI_CLOCKWISE;
// 0 or 2 (odd number of swaps to get to index 3)
if (idxOfHyd == 0 || idxOfHyd == 2)
winding = winding.invert();
return new TetrahedralChirality(focus, carriers, winding);
}
use of org.openscience.cdk.interfaces.ITetrahedralChirality.Stereo in project cdk by cdk.
the class InChIGenerator method generateInchiFromCDKAtomContainer.
/**
* <p>Reads atoms, bonds etc from atom container and converts to format
* InChI library requires, then places call for the library to generate
* the InChI.
*
* @param atomContainer AtomContainer to generate InChI for.
* @param ignore Ignore aromatic bonds
* @throws CDKException
*/
private void generateInchiFromCDKAtomContainer(IAtomContainer atomContainer, boolean ignore) throws CDKException {
this.atomContainer = atomContainer;
Iterator<IAtom> atoms = atomContainer.atoms().iterator();
// Check for 3d coordinates
boolean all3d = true;
boolean all2d = true;
while (atoms.hasNext()) {
IAtom atom = atoms.next();
if (atom.getPoint3d() == null) {
all3d = false;
}
if (atom.getPoint2d() == null) {
all2d = false;
}
}
Map<IAtom, InchiAtom> atomMap = new HashMap<>();
atoms = atomContainer.atoms().iterator();
while (atoms.hasNext()) {
IAtom atom = atoms.next();
// Get coordinates
// Use 3d if possible, otherwise 2d or none
double x, y, z;
if (all3d) {
Point3d p = atom.getPoint3d();
x = p.x;
y = p.y;
z = p.z;
} else if (all2d) {
Point2d p = atom.getPoint2d();
x = p.x;
y = p.y;
z = 0.0;
} else {
x = 0.0;
y = 0.0;
z = 0.0;
}
// Chemical element symbol
String el = atom.getSymbol();
// Generate InChI atom
InchiAtom iatom = new InchiAtom(el, x, y, z);
input.addAtom(iatom);
atomMap.put(atom, iatom);
// Check if charged
int charge = atom.getFormalCharge();
if (charge != 0) {
iatom.setCharge(charge);
}
// Check whether isotopic
Integer isotopeNumber = atom.getMassNumber();
if (isotopeNumber != null) {
iatom.setIsotopicMass(isotopeNumber);
}
// Check for implicit hydrogens
// atom.getHydrogenCount() returns number of implict hydrogens, not
// total number
// Ref: Posting to cdk-devel list by Egon Willighagen 2005-09-17
Integer implicitH = atom.getImplicitHydrogenCount();
// set implicit hydrogen count, -1 tells the inchi to determine it
iatom.setImplicitHydrogen(implicitH != null ? implicitH : -1);
// Check if radical
int count = atomContainer.getConnectedSingleElectronsCount(atom);
if (count == 1) {
iatom.setRadical(InchiRadical.DOUBLET);
} else if (count == 2) {
Enum spin = atom.getProperty(CDKConstants.SPIN_MULTIPLICITY);
if (spin != null) {
// a little brittle
if (spin.name().equals("DivalentSinglet"))
iatom.setRadical(InchiRadical.SINGLET);
else
iatom.setRadical(InchiRadical.TRIPLET);
} else {
iatom.setRadical(InchiRadical.TRIPLET);
}
} else if (count != 0) {
throw new CDKException("Unrecognised radical type");
}
}
// Process bonds
for (IBond bond : atomContainer.bonds()) {
// Assumes 2 centre bond
InchiAtom at0 = atomMap.get(bond.getBegin());
InchiAtom at1 = atomMap.get(bond.getEnd());
// Get bond order
InchiBondType order;
Order bo = bond.getOrder();
if (!ignore && bond.isAromatic()) {
order = InchiBondType.ALTERN;
} else if (bo == Order.SINGLE) {
order = InchiBondType.SINGLE;
} else if (bo == Order.DOUBLE) {
order = InchiBondType.DOUBLE;
} else if (bo == Order.TRIPLE) {
order = InchiBondType.TRIPLE;
} else {
throw new CDKException("Failed to generate InChI: Unsupported bond type");
}
// Create InChI bond
// Check for bond stereo definitions
IBond.Stereo display = bond.getStereo();
final InchiBondStereo iDisplay;
switch(display) {
case UP:
iDisplay = InchiBondStereo.SINGLE_1UP;
break;
case UP_INVERTED:
iDisplay = InchiBondStereo.SINGLE_2UP;
break;
case DOWN:
iDisplay = InchiBondStereo.SINGLE_1DOWN;
break;
case DOWN_INVERTED:
iDisplay = InchiBondStereo.SINGLE_2DOWN;
break;
case UP_OR_DOWN:
iDisplay = InchiBondStereo.SINGLE_1EITHER;
break;
case UP_OR_DOWN_INVERTED:
iDisplay = InchiBondStereo.SINGLE_2EITHER;
break;
case E_OR_Z:
iDisplay = InchiBondStereo.DOUBLE_EITHER;
break;
default:
iDisplay = InchiBondStereo.NONE;
break;
}
/*
TODO: old code would set single/double either if no display?
*/
InchiBond ibond = new InchiBond(at0, at1, order, iDisplay);
input.addBond(ibond);
}
// Process tetrahedral stereo elements
for (IStereoElement stereoElem : atomContainer.stereoElements()) {
if (stereoElem instanceof ITetrahedralChirality) {
ITetrahedralChirality chirality = (ITetrahedralChirality) stereoElem;
IAtom[] surroundingAtoms = chirality.getLigands();
Stereo stereoType = chirality.getStereo();
InchiAtom atC = atomMap.get(chirality.getChiralAtom());
InchiAtom at0 = atomMap.get(surroundingAtoms[0]);
InchiAtom at1 = atomMap.get(surroundingAtoms[1]);
InchiAtom at2 = atomMap.get(surroundingAtoms[2]);
InchiAtom at3 = atomMap.get(surroundingAtoms[3]);
InchiStereoParity p;
if (stereoType == Stereo.ANTI_CLOCKWISE) {
p = InchiStereoParity.ODD;
} else if (stereoType == Stereo.CLOCKWISE) {
p = InchiStereoParity.EVEN;
} else {
throw new CDKException("Unknown tetrahedral chirality");
}
InchiStereo jniStereo = InchiStereo.createTetrahedralStereo(atC, at0, at1, at2, at3, p);
input.addStereo(jniStereo);
} else if (stereoElem instanceof IDoubleBondStereochemistry) {
IDoubleBondStereochemistry dbStereo = (IDoubleBondStereochemistry) stereoElem;
IBond[] surroundingBonds = dbStereo.getBonds();
if (surroundingBonds[0] == null || surroundingBonds[1] == null)
throw new CDKException("Cannot generate an InChI with incomplete double bond info");
org.openscience.cdk.interfaces.IDoubleBondStereochemistry.Conformation stereoType = dbStereo.getStereo();
IBond stereoBond = dbStereo.getStereoBond();
InchiAtom at0;
InchiAtom at1;
InchiAtom at2;
InchiAtom at3;
// create a double bond stereochemistry
if (stereoBond.contains(surroundingBonds[0].getBegin())) {
// first atom is A
at1 = atomMap.get(surroundingBonds[0].getBegin());
at0 = atomMap.get(surroundingBonds[0].getEnd());
} else {
// first atom is X
at0 = atomMap.get(surroundingBonds[0].getBegin());
at1 = atomMap.get(surroundingBonds[0].getEnd());
}
if (stereoBond.contains(surroundingBonds[1].getBegin())) {
// first atom is B
at2 = atomMap.get(surroundingBonds[1].getBegin());
at3 = atomMap.get(surroundingBonds[1].getEnd());
} else {
// first atom is Y
at2 = atomMap.get(surroundingBonds[1].getEnd());
at3 = atomMap.get(surroundingBonds[1].getBegin());
}
InchiStereoParity p;
if (stereoType == org.openscience.cdk.interfaces.IDoubleBondStereochemistry.Conformation.TOGETHER) {
p = InchiStereoParity.ODD;
} else if (stereoType == org.openscience.cdk.interfaces.IDoubleBondStereochemistry.Conformation.OPPOSITE) {
p = InchiStereoParity.EVEN;
} else {
throw new CDKException("Unknown double bond stereochemistry");
}
input.addStereo(InchiStereo.createDoubleBondStereo(at0, at1, at2, at3, p));
} else if (stereoElem instanceof ExtendedTetrahedral) {
ExtendedTetrahedral extendedTetrahedral = (ExtendedTetrahedral) stereoElem;
Stereo winding = extendedTetrahedral.winding();
// The periphals (p<i>) and terminals (t<i>) are refering to
// the following atoms. The focus (f) is also shown.
//
// p0 p2
// \ /
// t0 = f = t1
// / \
// p1 p3
IAtom focus = extendedTetrahedral.getFocus();
IAtom[] terminals = extendedTetrahedral.findTerminalAtoms(atomContainer);
IAtom[] peripherals = extendedTetrahedral.peripherals();
// InChI only supports length 2
if (ExtendedTetrahedral.getLength(atomContainer, focus) > 2)
continue;
// InChI API is particualar about the input, each terminal atom
// needs to be present in the list of neighbors and they must
// be at index 1 and 2 (i.e. in the middle). This is true even
// of explict atoms. For the implicit atoms, the terminals may
// be in the peripherals allready and so we correct the winding
// and reposition as needed.
List<IBond> t0Bonds = onlySingleBonded(atomContainer.getConnectedBondsList(terminals[0]));
List<IBond> t1Bonds = onlySingleBonded(atomContainer.getConnectedBondsList(terminals[1]));
// with the terminal atom - the configuration does not change
if (t0Bonds.size() == 2) {
IAtom replace = t0Bonds.remove(0).getOther(terminals[0]);
for (int i = 0; i < peripherals.length; i++) if (replace == peripherals[i])
peripherals[i] = terminals[0];
}
if (t1Bonds.size() == 2) {
IAtom replace = t1Bonds.remove(0).getOther(terminals[1]);
for (int i = 0; i < peripherals.length; i++) if (replace == peripherals[i])
peripherals[i] = terminals[1];
}
// the neighbor attached to each terminal atom that we will
// define the configuration of
IAtom t0Neighbor = t0Bonds.get(0).getOther(terminals[0]);
IAtom t1Neighbor = t1Bonds.get(0).getOther(terminals[1]);
// everytime we exchange atoms the configuration inverts
for (int i = 0; i < peripherals.length; i++) {
if (i != 0 && t0Neighbor.equals(peripherals[i])) {
swap(peripherals, i, 0);
winding = winding.invert();
} else if (i != 1 && terminals[0].equals(peripherals[i])) {
swap(peripherals, i, 1);
winding = winding.invert();
} else if (i != 2 && terminals[1].equals(peripherals[i])) {
swap(peripherals, i, 2);
winding = winding.invert();
} else if (i != 3 && t1Neighbor.equals(peripherals[i])) {
swap(peripherals, i, 3);
winding = winding.invert();
}
}
InchiStereoParity parity;
if (winding == Stereo.ANTI_CLOCKWISE)
parity = InchiStereoParity.ODD;
else if (winding == Stereo.CLOCKWISE)
parity = InchiStereoParity.EVEN;
else
throw new CDKException("Unknown extended tetrahedral chirality");
input.addStereo(InchiStereo.createAllenalStereo(atomMap.get(focus), atomMap.get(peripherals[0]), atomMap.get(peripherals[1]), atomMap.get(peripherals[2]), atomMap.get(peripherals[3]), parity));
}
}
output = JnaInchi.toInchi(input, options);
}
use of org.openscience.cdk.interfaces.ITetrahedralChirality.Stereo in project cdk by cdk.
the class CIPToolTest method testOla28.
@Test
public void testOla28() throws Exception {
String filename = "mol28.cml";
InputStream ins = this.getClass().getResourceAsStream(filename);
CMLReader reader = new CMLReader(ins);
IChemFile file = reader.read(new ChemFile());
reader.close();
IAtomContainer mol = ChemFileManipulator.getAllAtomContainers(file).get(0);
for (IAtom atom : mol.atoms()) {
List<IAtom> neighbors = mol.getConnectedAtomsList(atom);
if (neighbors.size() == 4) {
Stereo stereo = StereoTool.getStereo(neighbors.get(0), neighbors.get(1), neighbors.get(2), neighbors.get(3));
ITetrahedralChirality stereoCenter = new TetrahedralChirality(mol.getAtom(0), neighbors.toArray(new IAtom[] {}), stereo);
CIP_CHIRALITY chirality = CIPTool.getCIPChirality(mol, stereoCenter);
}
}
}
Aggregations