Search in sources :

Example 1 with ITetrahedralChirality

use of org.openscience.cdk.interfaces.ITetrahedralChirality in project cdk by cdk.

the class QueryStereoFilter method indexElements.

/**
 * Index the stereo elements of the {@code container} into the the {@code
 * elements} and {@code types} arrays. The {@code map} is used for looking
 * up the index of atoms.
 *
 * @param map       index of atoms
 * @param elements  array to fill with stereo elements
 * @param types     type of stereo element indexed
 * @param container the container to index the elements of
 * @return indices of atoms involved in stereo configurations
 */
private static int[] indexElements(Map<IAtom, Integer> map, IStereoElement[] elements, Type[] types, IAtomContainer container) {
    int[] indices = new int[container.getAtomCount()];
    int nElements = 0;
    for (IStereoElement element : container.stereoElements()) {
        if (element instanceof ITetrahedralChirality) {
            ITetrahedralChirality tc = (ITetrahedralChirality) element;
            int idx = map.get(tc.getChiralAtom());
            elements[idx] = element;
            types[idx] = Type.Tetrahedral;
            indices[nElements++] = idx;
        } else if (element instanceof IDoubleBondStereochemistry) {
            IDoubleBondStereochemistry dbs = (IDoubleBondStereochemistry) element;
            int idx1 = map.get(dbs.getStereoBond().getBegin());
            int idx2 = map.get(dbs.getStereoBond().getEnd());
            elements[idx2] = elements[idx1] = element;
            types[idx1] = types[idx2] = Type.Geometric;
            // only visit the first atom
            indices[nElements++] = idx1;
        }
    }
    return Arrays.copyOf(indices, nElements);
}
Also used : IDoubleBondStereochemistry(org.openscience.cdk.interfaces.IDoubleBondStereochemistry) ITetrahedralChirality(org.openscience.cdk.interfaces.ITetrahedralChirality) IStereoElement(org.openscience.cdk.interfaces.IStereoElement)

Example 2 with ITetrahedralChirality

use of org.openscience.cdk.interfaces.ITetrahedralChirality in project cdk by cdk.

the class QueryStereoFilter method checkTetrahedral.

/**
 * Verify the tetrahedral stereo-chemistry (clockwise/anticlockwise) of atom
 * {@code u} is preserved in the target when the {@code mapping} is used.
 *
 * @param u       tetrahedral index in the target
 * @param mapping mapping of vertices
 * @return the tetrahedral configuration is preserved
 */
private boolean checkTetrahedral(int u, int[] mapping) {
    int v = mapping[u];
    if (targetTypes[v] != null && targetTypes[v] != Type.Tetrahedral)
        return false;
    ITetrahedralChirality queryElement = (ITetrahedralChirality) queryElements[u];
    ITetrahedralChirality targetElement = (ITetrahedralChirality) targetElements[v];
    IAtom queryAtom = query.getAtom(u);
    IAtom targetAtom = target.getAtom(v);
    // check if unspecified was allowed
    if (targetTypes[v] == null)
        return ((QueryAtom) queryAtom).getExpression().matches(targetAtom, 0);
    // target was non-tetrahedral
    if (targetTypes[v] != Type.Tetrahedral)
        return false;
    int[] us = map(u, v, neighbors(queryElement, queryMap), mapping);
    int[] vs = neighbors(targetElement, targetMap);
    // adjustment needed for implicit neighbor (H or lone pair)
    int focusIdx = targetMap.get(targetAtom);
    for (int i = 0; i < 4; i++) {
        // find mol neighbor in mapped query list
        int j = indexOf(us, vs[i]);
        // (which we store as focusIdx) with this neighbor
        if (j < 0)
            us[indexOf(us, focusIdx)] = vs[i];
    }
    int parity = permutationParity(us) * permutationParity(vs) * parity(targetElement.getStereo());
    int groupInfo = targetElement.getGroupInfo();
    if (groupInfo != 0) {
        if (groupConfigAdjust == null)
            groupConfigAdjust = new int[target.getAtomCount()];
        // initialise the group
        if (groupConfigAdjust[v] == 0) {
            boolean leftOk = ((QueryAtom) queryAtom).getExpression().matches(targetAtom, IStereoElement.LEFT);
            boolean rghtOk = ((QueryAtom) queryAtom).getExpression().matches(targetAtom, IStereoElement.RIGHT);
            // element so wait till we find the next one
            if (leftOk && rghtOk) {
                return true;
            }
            int adjust = 1;
            if ((parity == -1 && !leftOk) || (parity == 1 && !rghtOk))
                adjust = -1;
            for (int idx : targetStereoIndices) {
                if (targetElements[idx].getGroupInfo() == groupInfo) {
                    groupConfigAdjust[idx] = adjust;
                }
            }
        }
        // make the adjustment
        parity *= groupConfigAdjust[v];
    }
    if (parity < 0)
        return ((QueryAtom) queryAtom).getExpression().matches(targetAtom, IStereoElement.LEFT);
    else if (parity > 0)
        return ((QueryAtom) queryAtom).getExpression().matches(targetAtom, IStereoElement.RIGHT);
    else
        return ((QueryAtom) queryAtom).getExpression().matches(targetAtom, 0);
}
Also used : ITetrahedralChirality(org.openscience.cdk.interfaces.ITetrahedralChirality) IAtom(org.openscience.cdk.interfaces.IAtom) QueryAtom(org.openscience.cdk.isomorphism.matchers.QueryAtom)

Example 3 with ITetrahedralChirality

use of org.openscience.cdk.interfaces.ITetrahedralChirality in project cdk by cdk.

the class StereoMatch method indexElements.

/**
 * Index the stereo elements of the {@code container} into the the {@code
 * elements} and {@code types} arrays. The {@code map} is used for looking
 * up the index of atoms.
 *
 * @param map       index of atoms
 * @param elements  array to fill with stereo elements
 * @param types     type of stereo element indexed
 * @param container the container to index the elements of
 * @return indices of atoms involved in stereo configurations
 */
private static int[] indexElements(Map<IAtom, Integer> map, IStereoElement[] elements, Type[] types, IAtomContainer container) {
    int[] indices = new int[container.getAtomCount()];
    int nElements = 0;
    for (IStereoElement element : container.stereoElements()) {
        if (element instanceof ITetrahedralChirality) {
            ITetrahedralChirality tc = (ITetrahedralChirality) element;
            int idx = map.get(tc.getChiralAtom());
            elements[idx] = element;
            types[idx] = Type.Tetrahedral;
            indices[nElements++] = idx;
        } else if (element instanceof IDoubleBondStereochemistry) {
            IDoubleBondStereochemistry dbs = (IDoubleBondStereochemistry) element;
            int idx1 = map.get(dbs.getStereoBond().getBegin());
            int idx2 = map.get(dbs.getStereoBond().getEnd());
            elements[idx2] = elements[idx1] = element;
            types[idx1] = types[idx2] = Type.Geometric;
            // only visit the first atom
            indices[nElements++] = idx1;
        }
    }
    return Arrays.copyOf(indices, nElements);
}
Also used : IDoubleBondStereochemistry(org.openscience.cdk.interfaces.IDoubleBondStereochemistry) ITetrahedralChirality(org.openscience.cdk.interfaces.ITetrahedralChirality) IStereoElement(org.openscience.cdk.interfaces.IStereoElement)

Example 4 with ITetrahedralChirality

use of org.openscience.cdk.interfaces.ITetrahedralChirality in project cdk by cdk.

the class FischerRecognition method recognise.

/**
 * Recognise the tetrahedral stereochemistry in the provided structure.
 *
 * @param projections allowed projection types
 * @return zero of more stereo elements
 */
List<IStereoElement> recognise(Set<Projection> projections) {
    if (!projections.contains(Projection.Fischer))
        return Collections.emptyList();
    // build atom index and only recognize 2D depictions
    Map<IAtom, Integer> atomToIndex = new HashMap<>();
    for (IAtom atom : container.atoms()) {
        if (atom.getPoint2d() == null)
            return Collections.emptyList();
        atomToIndex.put(atom, atomToIndex.size());
    }
    RingSearch ringSearch = new RingSearch(container, graph);
    final List<IStereoElement> elements = new ArrayList<>(5);
    for (int v = 0; v < container.getAtomCount(); v++) {
        IAtom focus = container.getAtom(v);
        Elements elem = Elements.ofNumber(focus.getAtomicNumber());
        if (elem != Carbon)
            continue;
        if (ringSearch.cyclic(v))
            continue;
        if (stereocenters.elementType(v) != Tetracoordinate)
            continue;
        if (!stereocenters.isStereocenter(v))
            continue;
        ITetrahedralChirality element = newTetrahedralCenter(focus, neighbors(v, graph, bonds));
        if (element == null)
            continue;
        // east/west bonds must be to terminal atoms
        IAtom east = element.getLigands()[EAST];
        IAtom west = element.getLigands()[WEST];
        if (!east.equals(focus) && !isTerminal(east, atomToIndex))
            continue;
        if (!west.equals(focus) && !isTerminal(west, atomToIndex))
            continue;
        elements.add(element);
    }
    return elements;
}
Also used : RingSearch(org.openscience.cdk.ringsearch.RingSearch) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Elements(org.openscience.cdk.config.Elements) ITetrahedralChirality(org.openscience.cdk.interfaces.ITetrahedralChirality) IAtom(org.openscience.cdk.interfaces.IAtom) IStereoElement(org.openscience.cdk.interfaces.IStereoElement)

Example 5 with ITetrahedralChirality

use of org.openscience.cdk.interfaces.ITetrahedralChirality in project cdk by cdk.

the class AtomContainerManipulator method convertImplicitToExplicitHydrogens.

/**
 * Adds explicit hydrogens (without coordinates) to the IAtomContainer,
 * equaling the number of set implicit hydrogens.
 *
 * @param atomContainer the atom container to consider
 * @cdk.keyword hydrogens, adding
 */
public static void convertImplicitToExplicitHydrogens(IAtomContainer atomContainer) {
    List<IAtom> hydrogens = new ArrayList<>();
    List<IBond> newBonds = new ArrayList<>();
    // store a single explicit hydrogen of each original neighbor
    Map<IAtom, IAtom> hNeighbor = new HashMap<>(2 * atomContainer.getAtomCount());
    for (IAtom atom : atomContainer.atoms()) {
        if (atom.getAtomicNumber() != IElement.H) {
            Integer hCount = atom.getImplicitHydrogenCount();
            if (hCount != null) {
                for (int i = 0; i < hCount; i++) {
                    IAtom hydrogen = atom.getBuilder().newInstance(IAtom.class, "H");
                    hydrogen.setAtomTypeName("H");
                    hydrogen.setImplicitHydrogenCount(0);
                    hydrogens.add(hydrogen);
                    newBonds.add(atom.getBuilder().newInstance(IBond.class, atom, hydrogen, Order.SINGLE));
                    if (hNeighbor.get(atom) == null)
                        hNeighbor.put(atom, hydrogen);
                }
                atom.setImplicitHydrogenCount(0);
            }
        }
    }
    for (IAtom atom : hydrogens) atomContainer.addAtom(atom);
    for (IBond bond : newBonds) atomContainer.addBond(bond);
    // update stereo elements with an implicit part
    List<IStereoElement> stereos = new ArrayList<>();
    for (IStereoElement stereo : atomContainer.stereoElements()) {
        if (stereo instanceof ITetrahedralChirality) {
            ITetrahedralChirality tc = (ITetrahedralChirality) stereo;
            IAtom focus = tc.getFocus();
            IAtom[] carriers = tc.getCarriers().toArray(new IAtom[4]);
            IAtom hydrogen = hNeighbor.get(focus);
            if (hydrogen != null) {
                replaceAtom(carriers, focus, hydrogen);
                TetrahedralChirality newStereo = new TetrahedralChirality(focus, carriers, tc.getStereo());
                newStereo.setGroupInfo(tc.getGroupInfo());
                stereos.add(newStereo);
            } else {
                stereos.add(stereo);
            }
        } else if (stereo instanceof ExtendedTetrahedral) {
            ExtendedTetrahedral tc = (ExtendedTetrahedral) stereo;
            IAtom focus = tc.getFocus();
            IAtom[] carriers = tc.getCarriers().toArray(new IAtom[4]);
            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);
            }
        } else {
            stereos.add(stereo);
        }
    }
    atomContainer.setStereoElements(stereos);
}
Also used : ITetrahedralChirality(org.openscience.cdk.interfaces.ITetrahedralChirality) TetrahedralChirality(org.openscience.cdk.stereo.TetrahedralChirality) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) IBond(org.openscience.cdk.interfaces.IBond) ITetrahedralChirality(org.openscience.cdk.interfaces.ITetrahedralChirality) ExtendedTetrahedral(org.openscience.cdk.stereo.ExtendedTetrahedral) IAtom(org.openscience.cdk.interfaces.IAtom) IStereoElement(org.openscience.cdk.interfaces.IStereoElement)

Aggregations

ITetrahedralChirality (org.openscience.cdk.interfaces.ITetrahedralChirality)89 Test (org.junit.Test)64 IAtom (org.openscience.cdk.interfaces.IAtom)64 IAtomContainer (org.openscience.cdk.interfaces.IAtomContainer)48 IStereoElement (org.openscience.cdk.interfaces.IStereoElement)41 IBond (org.openscience.cdk.interfaces.IBond)27 ArrayList (java.util.ArrayList)13 AtomContainer (org.openscience.cdk.silent.AtomContainer)12 TetrahedralChirality (org.openscience.cdk.stereo.TetrahedralChirality)12 Bond (org.openscience.cdk.silent.Bond)11 IChemObjectBuilder (org.openscience.cdk.interfaces.IChemObjectBuilder)10 HashMap (java.util.HashMap)9 IDoubleBondStereochemistry (org.openscience.cdk.interfaces.IDoubleBondStereochemistry)9 ExtendedTetrahedral (org.openscience.cdk.stereo.ExtendedTetrahedral)5 Point3d (javax.vecmath.Point3d)3 CDKException (org.openscience.cdk.exception.CDKException)3 CIP_CHIRALITY (org.openscience.cdk.geometry.cip.CIPTool.CIP_CHIRALITY)3 Stereo (org.openscience.cdk.interfaces.ITetrahedralChirality.Stereo)3 QueryAtom (org.openscience.cdk.isomorphism.matchers.QueryAtom)3 Matcher (java.util.regex.Matcher)2