All Downloads are FREE. Search and download functionalities are using the official Maven repository.

uk.ac.ebi.beam.ToTrigonalTopology Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2013, European Bioinformatics Institute (EMBL-EBI)
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * The views and conclusions contained in the software and documentation are those
 * of the authors and should not be interpreted as representing official policies,
 * either expressed or implied, of the FreeBSD Project.
 */

package uk.ac.ebi.beam;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Convert direction (up/down) bonds to trigonal topology (double bond atom
 * centric stereo specification).
 *
 * 
 *    F/C=C/F -> F/[C@H]=[C@H]F
 *    F/C=C\F -> F/[C@H]=[C@@H]F
 *    F\C=C/F -> F/[C@@H]=[C@H]F
 *    F\C=C\F -> F/[C@@H]=[C@@H]F
 * 
* * @author John May */ final class ToTrigonalTopology extends AbstractFunction { public Graph apply(Graph g) { Graph h = new Graph(g.order()); // original topology information this is unchanged for (int u = 0; u < g.order(); u++) { h.addTopology(g.topologyOf(u)); } Map replacements = new HashMap(); // change edges (only changed added to replacement) for (int u = 0; u < g.order(); u++) { for (final Edge e : g.edges(u)) { if (e.other(u) > u && e.bond().directional()) { replacements.put(e, new Edge(u, e.other(u), Bond.IMPLICIT)); } } } List es = doubleBondLabelledEdges(g); for (Edge e : es) { int u = e.either(); int v = e.other(u); // add to topologies h.addTopology(toTrigonal(g, e, u)); h.addTopology(toTrigonal(g, e, v)); } for (int u = 0; u < g.order(); u++) { Atom a = g.atom(u); if (a.subset() && h.topologyOf(u) != Topology.unknown()) { h.addAtom(asBracketAtom(u, g)); } else { h.addAtom(a); } } // append the edges, replacing any which need to be changed for (int u = 0; u < g.order(); u++) { for (Edge e : g.edges(u)) { if (e.other(u) > u) { Edge replacement = replacements.get(e); if (replacement != null) e = replacement; h.addEdge(e); } } } return h; } private Atom asBracketAtom(int u, Graph g) { Atom a = g.atom(u); int sum = a.aromatic() ? 1 : 0; for (Edge e : g.edges(u)) { sum += e.bond().order(); } return new AtomImpl.BracketAtom(-1, a.element(), a.aromatic() ? a.element().aromaticImplicitHydrogens(sum) : a.element().implicitHydrogens(sum), 0, 0, a.aromatic()); } private Topology toTrigonal(Graph g, Edge e, int u) { List es = g.edges(u); int offset = es.indexOf(e); int parity = 0; // vertex information for topology int j = 0; int[] vs = new int[]{ e.other(u), // double bond u, // for implicit H u, // for implicit H }; if (es.size() == 2) { Edge e1 = es.get((offset + 1) % 2); Bond b = e1.bond(u); if (isUp(b)) { vs[1] = e1.other(u); } else if (isDown(b)) { vs[2] = e1.other(u); } } else if (es.size() == 3) { Edge e1 = es.get((offset + 1) % 3); Edge e2 = es.get((offset + 2) % 3); Bond b1 = e1.bond(u); Bond b2 = e2.bond(u); if (b1 == Bond.SINGLE || b1 == Bond.IMPLICIT) { if (isUp(b2)) { vs[1] = e2.other(u); vs[2] = e1.other(u); } else if (isDown(b2)) { vs[1] = e1.other(u); vs[2] = e2.other(u); } } else { if (isUp(b1)) { vs[1] = e1.other(u); vs[2] = e2.other(u); } else if (isDown(b1)) { vs[1] = e2.other(u); vs[2] = e1.other(u); } } } if (vs[1] == vs[2]) return Topology.unknown(); Configuration c = es.get(offset).other(u) < u ? Configuration.DB1 : Configuration.DB2; return Topology.trigonal(u, vs, c); } static boolean isUp(Bond b) { return b == Bond.UP || b == Bond.UP_AROMATIC; } static boolean isDown(Bond b) { return b == Bond.DOWN || b == Bond.DOWN_AROMATIC; } private List doubleBondLabelledEdges(Graph g) { List es = new ArrayList(); for (int u = 0; u < g.order(); u++) { for (Edge e : g.edges(u)) { if (e.other(u) > u && e.bond() == Bond.DOUBLE) { es.add(e); } } } return es; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy