Search in sources :

Example 1 with Stereo

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"));
    }
}
Also used : IAtomContainer(org.openscience.cdk.interfaces.IAtomContainer) IAtomContainer(org.openscience.cdk.interfaces.IAtomContainer) AtomContainer(org.openscience.cdk.AtomContainer) Stereo(org.openscience.cdk.interfaces.ITetrahedralChirality.Stereo) ExtendedTetrahedral(org.openscience.cdk.stereo.ExtendedTetrahedral) IAtom(org.openscience.cdk.interfaces.IAtom) Atom(org.openscience.cdk.Atom) IStereoElement(org.openscience.cdk.interfaces.IStereoElement) Test(org.junit.Test)

Example 2 with Stereo

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]"));
    }
}
Also used : IAtomContainer(org.openscience.cdk.interfaces.IAtomContainer) IAtomContainer(org.openscience.cdk.interfaces.IAtomContainer) AtomContainer(org.openscience.cdk.silent.AtomContainer) Stereo(org.openscience.cdk.interfaces.ITetrahedralChirality.Stereo) ExtendedTetrahedral(org.openscience.cdk.stereo.ExtendedTetrahedral) PseudoAtom(org.openscience.cdk.silent.PseudoAtom) IAtom(org.openscience.cdk.interfaces.IAtom) Atom(org.openscience.cdk.silent.Atom) IStereoElement(org.openscience.cdk.interfaces.IStereoElement) Test(org.junit.Test)

Example 3 with Stereo

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);
}
Also used : TetrahedralChirality(org.openscience.cdk.stereo.TetrahedralChirality) Stereo(org.openscience.cdk.interfaces.ITetrahedralChirality.Stereo) IAtom(org.openscience.cdk.interfaces.IAtom)

Example 4 with Stereo

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);
}
Also used : HashMap(java.util.HashMap) IBond(org.openscience.cdk.interfaces.IBond) InchiStereo(io.github.dan2097.jnainchi.InchiStereo) InchiBond(io.github.dan2097.jnainchi.InchiBond) InchiStereoParity(io.github.dan2097.jnainchi.InchiStereoParity) Point3d(javax.vecmath.Point3d) InchiAtom(io.github.dan2097.jnainchi.InchiAtom) IAtom(org.openscience.cdk.interfaces.IAtom) Order(org.openscience.cdk.interfaces.IBond.Order) CDKException(org.openscience.cdk.exception.CDKException) IDoubleBondStereochemistry(org.openscience.cdk.interfaces.IDoubleBondStereochemistry) Stereo(org.openscience.cdk.interfaces.ITetrahedralChirality.Stereo) InchiBondStereo(io.github.dan2097.jnainchi.InchiBondStereo) InchiStereo(io.github.dan2097.jnainchi.InchiStereo) Point2d(javax.vecmath.Point2d) InchiBondType(io.github.dan2097.jnainchi.InchiBondType) InchiBondStereo(io.github.dan2097.jnainchi.InchiBondStereo) ITetrahedralChirality(org.openscience.cdk.interfaces.ITetrahedralChirality) ExtendedTetrahedral(org.openscience.cdk.stereo.ExtendedTetrahedral) IStereoElement(org.openscience.cdk.interfaces.IStereoElement)

Example 5 with Stereo

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);
        }
    }
}
Also used : ITetrahedralChirality(org.openscience.cdk.interfaces.ITetrahedralChirality) TetrahedralChirality(org.openscience.cdk.stereo.TetrahedralChirality) CMLReader(org.openscience.cdk.io.CMLReader) IAtomContainer(org.openscience.cdk.interfaces.IAtomContainer) CIP_CHIRALITY(org.openscience.cdk.geometry.cip.CIPTool.CIP_CHIRALITY) InputStream(java.io.InputStream) IChemFile(org.openscience.cdk.interfaces.IChemFile) ChemFile(org.openscience.cdk.silent.ChemFile) IChemFile(org.openscience.cdk.interfaces.IChemFile) Stereo(org.openscience.cdk.interfaces.ITetrahedralChirality.Stereo) ITetrahedralChirality(org.openscience.cdk.interfaces.ITetrahedralChirality) IAtom(org.openscience.cdk.interfaces.IAtom) Test(org.junit.Test)

Aggregations

Stereo (org.openscience.cdk.interfaces.ITetrahedralChirality.Stereo)14 IAtom (org.openscience.cdk.interfaces.IAtom)12 Test (org.junit.Test)8 IAtomContainer (org.openscience.cdk.interfaces.IAtomContainer)8 IStereoElement (org.openscience.cdk.interfaces.IStereoElement)8 ExtendedTetrahedral (org.openscience.cdk.stereo.ExtendedTetrahedral)7 TetrahedralChirality (org.openscience.cdk.stereo.TetrahedralChirality)5 Atom (org.openscience.cdk.Atom)4 AtomContainer (org.openscience.cdk.AtomContainer)4 Point3d (javax.vecmath.Point3d)3 IBond (org.openscience.cdk.interfaces.IBond)3 ITetrahedralChirality (org.openscience.cdk.interfaces.ITetrahedralChirality)3 Point2d (javax.vecmath.Point2d)2 Atom (org.openscience.cdk.silent.Atom)2 AtomContainer (org.openscience.cdk.silent.AtomContainer)2 PseudoAtom (org.openscience.cdk.silent.PseudoAtom)2 DBStereo (ambit2.smarts.DoubleBondStereoInfo.DBStereo)1 InchiAtom (io.github.dan2097.jnainchi.InchiAtom)1 InchiBond (io.github.dan2097.jnainchi.InchiBond)1 InchiBondStereo (io.github.dan2097.jnainchi.InchiBondStereo)1