Skip to content

Commit

Permalink
Make it possible to obtain an atom-atom and bond-bond map all in one.…
Browse files Browse the repository at this point in the history
… This is more useful then either the atom-atom or bond-bond maps alone.

Signed-off-by: Egon Willighagen <egonw@users.sourceforge.net>
  • Loading branch information
johnmay authored and egonw committed Nov 21, 2014
1 parent 4949cd9 commit 940c8a3
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 4 deletions.
Expand Up @@ -35,6 +35,7 @@
import org.openscience.cdk.interfaces.IAtom;
import org.openscience.cdk.interfaces.IAtomContainer;
import org.openscience.cdk.interfaces.IBond;
import org.openscience.cdk.interfaces.IChemObject;
import org.openscience.cdk.isomorphism.matchers.IQueryAtomContainer;

import java.util.Iterator;
Expand Down Expand Up @@ -398,6 +399,28 @@ public Iterable<Map<IBond, IBond>> toBondMap() {
return map(new ToBondMap(query, target));
}

/**
* Convert the permutations to an atom-atom bond-bond map.
*
* <blockquote><pre>
* for (Map&lt;IChemObject,IChemObject&gt; map : mappings.toBondMap()) {
* for (Map.Entry&lt;IChemObject,IChemObject&gt; e : map.entrySet()) {
* IChemObject queryObj = e.getKey();
* IChemObject targetObj = e.getValue();
* }
*
* IAtom matchedAtom = map.get(query.getAtom(i));
* IBond matchedBond = map.get(query.getBond(i));
* }
* </pre></blockquote>
*
* @return iterable of atom-atom and bond-bond mappings
*/
@TestMethod("toAtomBondMap")
public Iterable<Map<IChemObject, IChemObject>> toAtomBondMap() {
return map(new ToAtomBondMap(query, target));
}

/**
* Efficiently determine if there are at least 'n' matches
*
Expand Down Expand Up @@ -530,4 +553,42 @@ public Map<IBond, IBond> apply(int[] mapping) {
return map.build();
}
}

/** Utility to transform a permutation into an atom-atom and bond-bond map. */
private final class ToAtomBondMap implements Function<int[], Map<IChemObject, IChemObject>> {

/** The query graph - indicates a presence of edges. */
private final int[][] g1;

/** Bond look ups for the query and target. */
private final GraphUtil.EdgeToBondMap bonds1, bonds2;

/**
* Use the provided query and target to obtain the bond instances.
*
* @param query the structure to be found
* @param target the structure being searched
*/
private ToAtomBondMap(IAtomContainer query, IAtomContainer target) {
this.bonds1 = GraphUtil.EdgeToBondMap.withSpaceFor(query);
this.bonds2 = GraphUtil.EdgeToBondMap.withSpaceFor(target);
this.g1 = GraphUtil.toAdjList(query, bonds1);
GraphUtil.toAdjList(target, bonds2);
}

/** @inheritDoc */
@Override
public Map<IChemObject, IChemObject> apply(int[] mapping) {
ImmutableMap.Builder<IChemObject, IChemObject> map = ImmutableMap.builder();
for (int u = 0; u < g1.length; u++) {
map.put(query.getAtom(u), target.getAtom(mapping[u]));
for (int v : g1[u]) {
if (v > u) {
map.put(bonds1.get(u, v), bonds2.get(mapping[u], mapping[v]));
}
}
}
return map.build();
}
}
}
Expand Up @@ -28,10 +28,7 @@
import com.google.common.base.Predicate;
import org.junit.Test;
import org.mockito.Matchers;
import org.openscience.cdk.interfaces.IAtom;
import org.openscience.cdk.interfaces.IAtomContainer;
import org.openscience.cdk.interfaces.IBond;
import org.openscience.cdk.interfaces.IChemObjectBuilder;
import org.openscience.cdk.interfaces.*;
import org.openscience.cdk.silent.SilentChemObjectBuilder;
import org.openscience.cdk.smiles.SmilesParser;

Expand Down Expand Up @@ -208,6 +205,31 @@ public void toBondMap() throws Exception {
assertFalse(iterator.hasNext());
}

@Test
public void toAtomBondMap() throws Exception {
IAtomContainer query = smi("CCC");
IAtomContainer target = smi("CCC");

Iterable<Map<IChemObject, IChemObject>> iterable = Pattern.findIdentical(query).matchAll(target).toAtomBondMap();
Iterator<Map<IChemObject, IChemObject>> iterator = iterable.iterator();

assertTrue(iterator.hasNext());
Map<IChemObject, IChemObject> m1 = iterator.next();
assertThat(m1.get(query.getAtom(0)), is((IChemObject)target.getAtom(0)));
assertThat(m1.get(query.getAtom(1)), is((IChemObject)target.getAtom(1)));
assertThat(m1.get(query.getAtom(2)), is((IChemObject)target.getAtom(2)));
assertThat(m1.get(query.getBond(0)), is((IChemObject)target.getBond(0)));
assertThat(m1.get(query.getBond(1)), is((IChemObject)target.getBond(1)));
assertTrue(iterator.hasNext());
Map<IChemObject, IChemObject> m2 = iterator.next();
assertThat(m2.get(query.getAtom(0)), is((IChemObject)target.getAtom(2)));
assertThat(m2.get(query.getAtom(1)), is((IChemObject)target.getAtom(1)));
assertThat(m2.get(query.getAtom(2)), is((IChemObject)target.getAtom(0)));
assertThat(m2.get(query.getBond(0)), is((IChemObject)target.getBond(1)));
assertThat(m2.get(query.getBond(1)), is((IChemObject)target.getBond(0)));
assertFalse(iterator.hasNext());
}

@Test
@SuppressWarnings("unchecked")
public void atLeast() throws Exception {
Expand Down

0 comments on commit 940c8a3

Please sign in to comment.