1 package org.openscience.cdk.smsd.labelling; 2 3 import org.openscience.cdk.CDKConstants; 4 import org.openscience.cdk.DefaultChemObjectBuilder; 5 import org.openscience.cdk.Mapping; 6 import org.openscience.cdk.Reaction; 7 import org.openscience.cdk.interfaces.IAtom; 8 import org.openscience.cdk.interfaces.IAtomContainer; 9 import org.openscience.cdk.interfaces.IAtomContainerSet; 10 import org.openscience.cdk.interfaces.IChemObject; 11 import org.openscience.cdk.interfaces.IMapping; 12 import org.openscience.cdk.interfaces.IReaction; 13 import org.openscience.cdk.tools.manipulator.ReactionManipulator; 14 15 import java.util.ArrayList; 16 import java.util.Collections; 17 import java.util.Comparator; 18 import java.util.HashMap; 19 import java.util.Hashtable; 20 import java.util.List; 21 import java.util.Map; 22 23 /** 24 * @cdk.module smsd 25 * @cdk.githash 26 * @deprecated This class is part of SMSD and either duplicates functionality elsewhere in the CDK or provides public 27 * access to internal implementation details. SMSD has been deprecated from the CDK with a newer, more recent 28 * version of SMSD is available at <a href="http://github.com/asad/smsd">http://github.com/asad/smsd</a>. 29 */ 30 @Deprecated 31 public class AbstractReactionLabeller { 32 33 /** 34 * A nasty hack necessary to get around a bug in the CDK 35 */ 36 private boolean fixAtomMappingCastType = false; 37 fixAtomMapping(IAtomContainer canonicalForm)38 private void fixAtomMapping(IAtomContainer canonicalForm) { 39 for (IAtom a : canonicalForm.atoms()) { 40 String v = (String) a.getProperty(CDKConstants.ATOM_ATOM_MAPPING); 41 if (v != null) { 42 a.setProperty(CDKConstants.ATOM_ATOM_MAPPING, Integer.valueOf(v)); 43 } 44 } 45 } 46 atomAtomMap(IReaction reaction, IReaction clone, Map<IAtomContainer, int[]> permutationMap)47 private Map<IAtom, IAtom> atomAtomMap(IReaction reaction, IReaction clone, Map<IAtomContainer, int[]> permutationMap) { 48 // create a Map of corresponding atoms for molecules 49 // (key: original Atom, value: clone Atom) 50 Map<IAtom, IAtom> atomAtom = new Hashtable<IAtom, IAtom>(); 51 IAtomContainerSet reactants = reaction.getReactants(); 52 IAtomContainerSet clonedReactants = clone.getReactants(); 53 for (int i = 0; i < reactants.getAtomContainerCount(); ++i) { 54 IAtomContainer mol = reactants.getAtomContainer(i); 55 IAtomContainer mol2 = clonedReactants.getAtomContainer(i); 56 int[] permutation = permutationMap.get(mol2); 57 for (int j = 0; j < mol.getAtomCount(); ++j) { 58 atomAtom.put(mol.getAtom(j), mol2.getAtom(permutation[j])); 59 } 60 } 61 IAtomContainerSet products = reaction.getProducts(); 62 IAtomContainerSet clonedProducts = clone.getProducts(); 63 for (int i = 0; i < products.getAtomContainerCount(); ++i) { 64 IAtomContainer mol = products.getAtomContainer(i); 65 IAtomContainer mol2 = clonedProducts.getAtomContainer(i); 66 int[] permutation = permutationMap.get(mol2); 67 for (int j = 0; j < mol.getAtomCount(); ++j) { 68 atomAtom.put(mol.getAtom(j), mol2.getAtom(permutation[j])); 69 } 70 } 71 72 for (IAtom key : atomAtom.keySet()) { 73 IAtomContainer keyAC = ReactionManipulator.getRelevantAtomContainer(reaction, key); 74 int keyIndex = keyAC.indexOf(key); 75 IAtom value = atomAtom.get(key); 76 IAtomContainer valueAC = ReactionManipulator.getRelevantAtomContainer(clone, value); 77 int valueIndex = valueAC.indexOf(value); 78 System.out.println("key " + keyIndex + key.getSymbol() + " mapped to " + valueIndex + value.getSymbol()); 79 } 80 81 return atomAtom; 82 } 83 cloneMappings(IReaction reaction, Map<IAtom, IAtom> atomAtomMap)84 private List<IMapping> cloneMappings(IReaction reaction, Map<IAtom, IAtom> atomAtomMap) { 85 // clone the mappings 86 int numberOfMappings = reaction.getMappingCount(); 87 List<IMapping> map = new ArrayList<IMapping>(); 88 for (int mappingIndex = 0; mappingIndex < numberOfMappings; mappingIndex++) { 89 IMapping mapping = reaction.getMapping(mappingIndex); 90 IChemObject keyChemObj0 = mapping.getChemObject(0); 91 IChemObject keyChemObj1 = mapping.getChemObject(1); 92 IChemObject co0 = (IChemObject) atomAtomMap.get(keyChemObj0); 93 IChemObject co1 = (IChemObject) atomAtomMap.get(keyChemObj1); 94 map.add(new Mapping(co0, co1)); 95 } 96 return map; 97 } 98 99 /** 100 * Clone and Sort the mappings based on the order of the first object 101 * in the mapping (which is assumed to be the reactant). 102 * 103 * @param reaction 104 */ cloneAndSortMappings(IReaction reaction, IReaction copyOfReaction, Map<IAtomContainer, int[]> permutationMap)105 private void cloneAndSortMappings(IReaction reaction, IReaction copyOfReaction, 106 Map<IAtomContainer, int[]> permutationMap) { 107 108 // make a lookup for the indices of the atoms in the copy 109 final Map<IChemObject, Integer> indexMap = new HashMap<IChemObject, Integer>(); 110 List<IAtomContainer> all = ReactionManipulator.getAllAtomContainers(copyOfReaction); 111 int globalIndex = 0; 112 for (IAtomContainer ac : all) { 113 for (IAtom atom : ac.atoms()) { 114 indexMap.put(atom, globalIndex); 115 globalIndex++; 116 } 117 } 118 119 Map<IAtom, IAtom> atomAtomMap = atomAtomMap(reaction, copyOfReaction, permutationMap); 120 List<IMapping> map = cloneMappings(reaction, atomAtomMap); 121 122 Comparator<IMapping> mappingSorter = new Comparator<IMapping>() { 123 124 /** 125 * {@inheritDoc} 126 */ 127 @Override 128 public int compare(IMapping o1, IMapping o2) { 129 IChemObject o10 = o1.getChemObject(0); 130 IChemObject o20 = o2.getChemObject(0); 131 return indexMap.get(o10).compareTo(indexMap.get(o20)); 132 } 133 134 }; 135 Collections.sort(map, mappingSorter); 136 int mappingIndex = 0; 137 for (IMapping mapping : map) { 138 mapping.getChemObject(0).setProperty(CDKConstants.ATOM_ATOM_MAPPING, mappingIndex); 139 mapping.getChemObject(1).setProperty(CDKConstants.ATOM_ATOM_MAPPING, mappingIndex); 140 copyOfReaction.addMapping(mapping); 141 mappingIndex++; 142 } 143 144 } 145 labelReaction(IReaction reaction, ICanonicalMoleculeLabeller labeller)146 public IReaction labelReaction(IReaction reaction, ICanonicalMoleculeLabeller labeller) { 147 System.out.println("labelling"); 148 IReaction canonReaction = new Reaction(); 149 150 Map<IAtomContainer, int[]> permutationMap = new HashMap<IAtomContainer, int[]>(); 151 152 IAtomContainerSet canonicalProducts = DefaultChemObjectBuilder.getInstance().newInstance( 153 IAtomContainerSet.class); 154 for (IAtomContainer product : reaction.getProducts().atomContainers()) { 155 IAtomContainer canonicalForm = labeller.getCanonicalMolecule(product); 156 if (fixAtomMappingCastType) { 157 fixAtomMapping(canonicalForm); 158 } 159 IAtomContainer canonicalMolecule = canonicalForm.getBuilder().newInstance(IAtomContainer.class, 160 canonicalForm); 161 permutationMap.put(canonicalMolecule, labeller.getCanonicalPermutation(product)); 162 canonicalProducts.addAtomContainer(canonicalMolecule); 163 } 164 IAtomContainerSet canonicalReactants = DefaultChemObjectBuilder.getInstance().newInstance( 165 IAtomContainerSet.class); 166 for (IAtomContainer reactant : reaction.getReactants().atomContainers()) { 167 IAtomContainer canonicalForm = labeller.getCanonicalMolecule(reactant); 168 if (fixAtomMappingCastType) { 169 fixAtomMapping(canonicalForm); 170 } 171 IAtomContainer canonicalMolecule = canonicalForm.getBuilder().newInstance(IAtomContainer.class, 172 canonicalForm); 173 permutationMap.put(canonicalMolecule, labeller.getCanonicalPermutation(reactant)); 174 canonicalReactants.addAtomContainer(canonicalMolecule); 175 } 176 canonReaction.setProducts(canonicalProducts); 177 canonReaction.setReactants(canonicalReactants); 178 cloneAndSortMappings(reaction, canonReaction, permutationMap); 179 return canonReaction; 180 } 181 182 } 183