Permalink
Browse files

Added a 'map' method on all IStereoElements. The map method allows a …

…stereo element on one container/molecule to mapped to a stereo element on another. This mapping is achieved using two symbol tables, one for atoms and one for bonds. All methods are null safe and the mapping will not fail if any content in the stereo elements is null. The mapping simplifies the cloning of molecules/atom containers but could also be used when comparing isomorphic graphs.
  • Loading branch information...
1 parent 96d6c1a commit 9c5670b9e363c66cdbef1afc352e25838f97ceb8 @johnmay committed Nov 1, 2012
@@ -28,10 +28,14 @@
package org.openscience.cdk;
import java.io.Serializable;
+import java.util.Map;
+import org.openscience.cdk.annotations.TestMethod;
import org.openscience.cdk.interfaces.IAtom;
import org.openscience.cdk.interfaces.IAtomParity;
+import org.openscience.cdk.interfaces.IBond;
import org.openscience.cdk.interfaces.IChemObjectBuilder;
+import org.openscience.cdk.interfaces.IStereoElement;
/**
* Represents the concept of an atom parity identifying the stereochemistry
@@ -151,7 +155,30 @@ public Object clone() throws CloneNotSupportedException {
clone.neighbors[3] = (IAtom)(neighbors[3].clone());
return clone;
}
-
+
+ /**
+ * @inheritDoc
+ */
+ @TestMethod("testMap_Map_Map,testMap_Null_Map,testMap_Map_Map_NullElement,testMap_Map_Map_EmptyMapping")
+ @Override
+ public IAtomParity map(Map<IAtom, IAtom> atoms, Map<IBond, IBond> bonds) {
+
+ if(atoms == null) // not using bond mapping
+ throw new IllegalArgumentException("null atom mapping provided");
+
+ // could map neighbours with a for loop but we need to pull individuals
+ // atoms for the constructor
+ return new AtomParity(
+ centralAtom != null ? atoms.get(centralAtom) : null,
+ neighbors[0] != null ? atoms.get(neighbors[0]) : null,
+ neighbors[1] != null ? atoms.get(neighbors[1]) : null,
+ neighbors[2] != null ? atoms.get(neighbors[2]) : null,
+ neighbors[3] != null ? atoms.get(neighbors[3]) : null,
+ parity
+ );
+
+ }
+
public IChemObjectBuilder getBuilder() {
return DefaultChemObjectBuilder.getInstance();
}
@@ -21,11 +21,16 @@
package org.openscience.cdk.debug;
import org.openscience.cdk.AtomParity;
+import org.openscience.cdk.annotations.TestMethod;
import org.openscience.cdk.interfaces.IAtom;
import org.openscience.cdk.interfaces.IAtomParity;
+import org.openscience.cdk.interfaces.IBond;
import org.openscience.cdk.tools.ILoggingTool;
import org.openscience.cdk.tools.LoggingToolFactory;
+import java.util.Map;
+import java.util.regex.Pattern;
+
/**
* Debugging data class.
*
@@ -36,6 +41,7 @@
public class DebugAtomParity extends AtomParity
implements IAtomParity {
+
private static final long serialVersionUID = 6305428844566539948L;
public DebugAtomParity(IAtom centralAtom, IAtom first, IAtom second, IAtom third, IAtom fourth, int parity) {
@@ -55,7 +61,35 @@ public IAtom getAtom() {
return super.getSurroundingAtoms();
}
- public int getParity() {
+ /**
+ * @inheritDoc
+ */
+ @TestMethod("testMap_Map_Map,testMap_Null_Map,testMap_Map_Map_NullElement,testMap_Map_Map_EmptyMapping")
+ @Override
+ public IAtomParity map(Map<IAtom, IAtom> atoms, Map<IBond, IBond> bonds) {
+
+ logger.debug("Mapping atom parity: " + atoms);
+
+ if(atoms == null) // not using bond mapping
+ throw new IllegalArgumentException("null atom mapping provided");
+
+ IAtom[] neighbors = getSurroundingAtoms();
+
+ // could map neighbours with a for loop but we need to pull individuals
+ // atoms for the constructor
+ return new DebugAtomParity(
+ getAtom() != null ? atoms.get(getAtom()) : null,
+ neighbors[0] != null ? atoms.get(neighbors[0]) : null,
+ neighbors[1] != null ? atoms.get(neighbors[1]) : null,
+ neighbors[2] != null ? atoms.get(neighbors[2]) : null,
+ neighbors[3] != null ? atoms.get(neighbors[3]) : null,
+ getParity()
+ );
+
+ }
+
+
+ public int getParity() {
logger.debug("Getting atom parity: ", super.getParity());
return super.getParity();
}
@@ -22,6 +22,8 @@
*/
package org.openscience.cdk.interfaces;
+import java.util.Map;
+
/**
* Represents the concept of an atom parity identifying the stereochemistry
* around an atom, given four neighbouring atoms.
@@ -58,7 +60,14 @@
* @return The parity value
*/
public int getParity();
-
+
+ /**
+ * @inheritDoc
+ */
+ @Override
+ public IAtomParity map(Map<IAtom, IAtom> atoms, Map<IBond, IBond> bonds);
+
+
}
@@ -22,6 +22,8 @@
*/
package org.openscience.cdk.interfaces;
+import java.util.Map;
+
/**
* Stereochemistry specification for double bond stereochemistry. The data model defines the double
* atoms and two ligands attached to those two atoms, linearly connected with the double bond in the
@@ -65,4 +67,10 @@
* @return the {@link Conformation} for this stereo element.
*/
public Conformation getStereo();
+
+ /**
+ * @inheritDoc
+ */
+ @Override
+ public IDoubleBondStereochemistry map(Map<IAtom, IAtom> atoms, Map<IBond, IBond> bonds);
}
@@ -22,6 +22,8 @@
*/
package org.openscience.cdk.interfaces;
+import java.util.Map;
+
/**
* Represents the concept of a stereo element in the molecule. Stereo elements can be
* that of quadrivalent atoms, cis/trans isomerism around double bonds, but also include
@@ -35,6 +37,23 @@
*/
public interface IStereoElement extends ICDKObject {
+ /**
+ * Map the atoms/bonds in this instance to a new stereo element using the
+ * provided atom/bond mapping. This allows the stereo element to be transferred
+ * between a cloned or aligned (i.e. isomorphic) chemical graph.
+ * <p/>
+ * If no mapping is found for a given atom or bond it is replaced with a null
+ * reference. However the provided atom and bonds maps must not be null.
+ *
+ * @param atoms non-null atom mapping, used to convert the original atoms to their mapped
+ * counterparts
+ * @param bonds non-null bond mapping, used to convert the original bonds to their mapped
+ * counterparts
+ * @return a new stereo element in the same configuration but with atoms/bonds
+ * replaced with their mapped equivalence.
+ */
+ public IStereoElement map(Map<IAtom, IAtom> atoms, Map<IBond, IBond> bonds);
+
}
@@ -22,6 +22,8 @@
*/
package org.openscience.cdk.interfaces;
+import java.util.Map;
+
/**
* Stereochemistry specification for quadrivalent atoms. The data model defines the central, chiral {@link IAtom},
* and its four ligand {@link IAtom}s, directly bonded to the chiral atom via an {@link IBond}. The ordering of the
@@ -63,4 +65,12 @@
*/
public Stereo getStereo();
+
+ /**
+ * @inheritDoc
+ */
+ @Override
+ public ITetrahedralChirality map(Map<IAtom, IAtom> atoms, Map<IBond, IBond> bonds);
+
+
}
@@ -23,9 +23,12 @@
package org.openscience.cdk.silent;
import java.io.Serializable;
+import java.util.Map;
+import org.openscience.cdk.annotations.TestMethod;
import org.openscience.cdk.interfaces.IAtom;
import org.openscience.cdk.interfaces.IAtomParity;
+import org.openscience.cdk.interfaces.IBond;
import org.openscience.cdk.interfaces.IChemObjectBuilder;
/**
@@ -146,7 +149,31 @@ public Object clone() throws CloneNotSupportedException {
clone.neighbors[3] = (IAtom)(neighbors[3].clone());
return clone;
}
-
+
+ /**
+ * @inheritDoc
+ */
+ @TestMethod("testMap_Map_Map,testMap_Null_Map,testMap_Map_Map_NullElement,testMap_Map_Map_EmptyMapping")
+ @Override
+ public IAtomParity map(Map<IAtom, IAtom> atoms, Map<IBond, IBond> bonds) {
+
+ if(atoms == null) // not using bond mapping
+ throw new IllegalArgumentException("null atom mapping provided");
+
+ // could map neighbours with a for loop but we need to pull individuals
+ // atoms for the constructor
+ return new AtomParity(
+ centralAtom != null ? atoms.get(centralAtom) : null,
+ neighbors[0] != null ? atoms.get(neighbors[0]) : null,
+ neighbors[1] != null ? atoms.get(neighbors[1]) : null,
+ neighbors[2] != null ? atoms.get(neighbors[2]) : null,
+ neighbors[3] != null ? atoms.get(neighbors[3]) : null,
+ parity
+ );
+
+ }
+
+
public IChemObjectBuilder getBuilder() {
return SilentChemObjectBuilder.getInstance();
}
@@ -24,9 +24,13 @@
import org.openscience.cdk.annotations.TestClass;
import org.openscience.cdk.annotations.TestMethod;
+import org.openscience.cdk.interfaces.IAtom;
import org.openscience.cdk.interfaces.IBond;
import org.openscience.cdk.interfaces.IChemObjectBuilder;
import org.openscience.cdk.interfaces.IDoubleBondStereochemistry;
+import org.openscience.cdk.interfaces.IStereoElement;
+
+import java.util.Map;
/**
* Stereochemistry specification for double bonds. See {@link IDoubleBondStereochemistry} for
@@ -93,4 +97,22 @@ public Conformation getStereo() {
return this.stereo;
}
+ @TestMethod("testMap_Map_Map,testMap_Null_Map,testMap_Map_Map_NullElement,testMap_Map_Map_EmptyMapping")
+ @Override
+ public IDoubleBondStereochemistry map(Map<IAtom, IAtom> atoms, Map<IBond, IBond> bonds) {
+
+ if(bonds == null)
+ throw new IllegalArgumentException("null bond mapping provided");
+
+ // map the double bond and the connected ligand bonds
+ IBond doubleBond = stereoBond != null ? bonds.get(stereoBond) : null;
+ IBond[] connected = new IBond[ligandBonds.length];
+
+ for(int i = 0; i < connected.length; i++){
+ if(ligandBonds[i] != null)
+ connected[i] = bonds.get(ligandBonds[i]);
+ }
+
+ return new DoubleBondStereochemistry(doubleBond, connected, stereo);
+ }
}
@@ -25,9 +25,13 @@
import org.openscience.cdk.annotations.TestClass;
import org.openscience.cdk.annotations.TestMethod;
import org.openscience.cdk.interfaces.IAtom;
+import org.openscience.cdk.interfaces.IBond;
import org.openscience.cdk.interfaces.IChemObjectBuilder;
+import org.openscience.cdk.interfaces.IStereoElement;
import org.openscience.cdk.interfaces.ITetrahedralChirality;
+import java.util.Map;
+
/**
* Stereochemistry specification for quadrivalent atoms. See {@link ITetrahedralChirality} for
* further details.
@@ -108,6 +112,31 @@ public IChemObjectBuilder getBuilder() {
}
/**
+ * @inheritDoc
+ */
+ @TestMethod("testMap_Map_Map,testMap_Null_Map,testMap_Map_Map_NullElement,testMap_Map_Map_EmptyMapping")
+ @Override
+ public ITetrahedralChirality map(Map<IAtom, IAtom> atoms, Map<IBond, IBond> bonds) {
+
+ // don't check bond map as we don't use it
+ if(atoms == null)
+ throw new IllegalArgumentException("null atom mapping provided");
+
+ // convert the chiral atom and it's ligands to their equivalent
+ IAtom chiral = chiralAtom != null ? atoms.get(chiralAtom) : null;
+ IAtom[] ligands = new IAtom[ligandAtoms.length];
+
+ for (int i = 0; i < ligands.length; i++) {
+ if(ligandAtoms[i] != null)
+ ligands[i] = atoms.get(ligandAtoms[i]);
+ }
+
+ // create a new tetrahedral instance with the mapped chiral atom and ligands
+ return new TetrahedralChirality(chiral, ligands, stereo);
+
+ }
+
+ /**
* Returns a {@link String} representation of this chiral element.
*
* @return the String representation
Oops, something went wrong.

0 comments on commit 9c5670b

Please sign in to comment.