Author: scooter
Date: 2013-02-08 16:16:32 -0800 (Fri, 08 Feb 2013)
New Revision: 31114
Added:
csplugins/trunk/ucsf/scooter/chemViz/src/chemViz/tasks/CDKRMapHandler.java
Modified:
csplugins/trunk/ucsf/scooter/chemViz/src/chemViz/tasks/AbstractCompoundTask.java
csplugins/trunk/ucsf/scooter/chemViz/src/chemViz/tasks/CreateMCSSTask.java
Log:
Changes to MCSS to improve performance. Also found
a problem with cdk's code not being thread safe. Had
to include a patched version of
src/chemViz/tasks/CDKRMapHandler.java as a stopgap
until this is fixed in the upstream code.
Modified:
csplugins/trunk/ucsf/scooter/chemViz/src/chemViz/tasks/AbstractCompoundTask.java
===================================================================
---
csplugins/trunk/ucsf/scooter/chemViz/src/chemViz/tasks/AbstractCompoundTask.java
2013-02-08 00:28:26 UTC (rev 31113)
+++
csplugins/trunk/ucsf/scooter/chemViz/src/chemViz/tasks/AbstractCompoundTask.java
2013-02-09 00:16:32 UTC (rev 31114)
@@ -135,12 +135,14 @@
if (threadList != null && threadList.size() > 0)
cList.addAll(GetCompoundTask.runThreads(maxThreads,
threadList));
+ /*
long endTime = Calendar.getInstance().getTimeInMillis();
System.out.println("getCompounds took:
"+(endTime-startTime)+"ms total");
System.out.println(" createStructure took:
"+Compound.totalTime+"ms");
System.out.println(" getFingerprint took:
"+Compound.totalFPTime+"ms");
System.out.println(" SMILES parsing took:
"+Compound.totalSMILESTime+"ms");
System.out.println(" creating the fingerprint took:
"+Compound.totalGetFPTime+"ms");
+ */
return cList;
}
Added:
csplugins/trunk/ucsf/scooter/chemViz/src/chemViz/tasks/CDKRMapHandler.java
===================================================================
--- csplugins/trunk/ucsf/scooter/chemViz/src/chemViz/tasks/CDKRMapHandler.java
(rev 0)
+++ csplugins/trunk/ucsf/scooter/chemViz/src/chemViz/tasks/CDKRMapHandler.java
2013-02-09 00:16:32 UTC (rev 31114)
@@ -0,0 +1,662 @@
+/* Copyright (C) 2006-2010 Syed Asad Rahman <[email protected]>
+ *
+ * Contact: [email protected]
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ * All we ask is that proper credit is given for our work, which includes
+ * - but is not limited to - adding the above copyright notice to the beginning
+ * of your source code files, and to any copyright notice that you may
distribute
+ * with programs based on this work.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received sourceAtom copy of the GNU Lesser General Public
License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+package org.openscience.cdk.smsd.algorithm.rgraph;
+
+import java.util.ArrayList;
+import java.util.BitSet;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Stack;
+import java.util.TreeMap;
+import org.openscience.cdk.annotations.TestClass;
+import org.openscience.cdk.exception.CDKException;
+import org.openscience.cdk.interfaces.IAtom;
+import org.openscience.cdk.interfaces.IAtomContainer;
+import org.openscience.cdk.interfaces.IBond;
+import org.openscience.cdk.smsd.helper.FinalMappings;
+import org.openscience.cdk.tools.manipulator.BondManipulator;
+
+/**
+ * This algorithm derives from the algorithm described in
+ * [Tonnelier, C. and Jauffret, Ph. and Hanser, Th. and Jauffret, Ph. and
Kaufmann, G.,
+ * Machine Learning of generic reactions:
+ * 3. An efficient algorithm for maximal common substructure determination,
+ * Tetrahedron Comput. Methodol., 1990, 3:351-358] and modified in the thesis
of
+ * T. Hanser [Unknown BibTeXML type: HAN93].
+ *
+ * @cdk.module smsd
+ * @cdk.githash
+ * @author Syed Asad Rahman <[email protected]>
+ */
+@TestClass("org.openscience.cdk.smsd.algorithm.cdk.CDKRMapHandlerTest")
+public class CDKRMapHandler {
+
+
+ public CDKRMapHandler(){
+
+ }
+ /**
+ * Returns source molecule
+ * @return the source
+ */
+ public IAtomContainer getSource() {
+ return source;
+ }
+
+ /**
+ * Set source molecule
+ * @param aSource the source to set
+ */
+ public void setSource(IAtomContainer aSource) {
+ source = aSource;
+ }
+
+ /**
+ * Returns target molecule
+ * @return the target
+ */
+ public IAtomContainer getTarget() {
+ return target;
+ }
+
+ /**
+ * Set target molecule
+ * @param aTarget the target to set
+ */
+ public void setTarget(IAtomContainer aTarget) {
+ target = aTarget;
+ }
+ private List<Map<Integer, Integer>> mappings;
+ private IAtomContainer source;
+ private IAtomContainer target;
+ private boolean timeoutFlag = false;
+
+ /**
+ * This function calculates all the possible combinations of MCS
+ * @param Molecule1
+ * @param Molecule2
+ * @param shouldMatchBonds
+ * @throws CDKException
+ */
+ public void calculateOverlapsAndReduce(IAtomContainer Molecule1,
IAtomContainer Molecule2, boolean shouldMatchBonds) throws CDKException {
+
+ // setSource(Molecule1);
+ // setTarget(Molecule2);
+
+ setMappings(new ArrayList<Map<Integer, Integer>>());
+
+
+ if ((Molecule1.getAtomCount() == 1) || (Molecule2.getAtomCount() ==
1)) {
+ List<CDKRMap> overlaps = CDKMCS.checkSingleAtomCases(Molecule1,
Molecule2);
+ int nAtomsMatched = overlaps.size();
+ nAtomsMatched = (nAtomsMatched > 0) ? 1 : 0;
+ if (nAtomsMatched > 0) {
+ /*UnComment this to get one Unique Mapping*/
+ //List reducedList =
removeRedundantMappingsForSingleAtomCase(overlaps);
+ //int counter = 0;
+ identifySingleAtomsMatchedParts(overlaps, Molecule1,
Molecule2);
+
+ }
+
+ } else {
+ List<List<CDKRMap>> overlaps = CDKMCS.search(Molecule1, Molecule2,
new BitSet(), new BitSet(), true, true, shouldMatchBonds);
+
+ List<List<CDKRMap>> reducedList = removeSubGraph(overlaps);
+ Stack<List<CDKRMap>> allMaxOverlaps = getAllMaximum(reducedList);
+ while (!allMaxOverlaps.empty()) {
+// System.out.println("source: " + source.getAtomCount() + ",
target: " + target.getAtomCount() + ", overl: " + allMaxOverlaps.peek().size());
+ List<List<CDKRMap>> maxOverlapsAtoms =
makeAtomsMapOfBondsMap(allMaxOverlaps.peek(), Molecule1, Molecule2);
+// System.out.println("size of maxOverlaps: " +
maxOverlapsAtoms.size());
+ identifyMatchedParts(maxOverlapsAtoms, Molecule1, Molecule2);
+// identifyMatchedParts(allMaxOverlaps.peek(), source, target);
+ allMaxOverlaps.pop();
+ }
+ }
+
+ FinalMappings.getInstance().set(getMappings());
+
+ }
+
+ /**
+ * This function calculates only one solution (exact) because we are
looking at the
+ * molecules which are exactly same in terms of the bonds and atoms
determined by the
+ * Fingerprint
+ * @param Molecule1
+ * @param Molecule2
+ * @param shouldMatchBonds
+ * @throws CDKException
+ */
+ public void calculateOverlapsAndReduceExactMatch(IAtomContainer Molecule1,
IAtomContainer Molecule2, boolean shouldMatchBonds) throws CDKException {
+
+ // setSource(Molecule1);
+ // setTarget(Molecule2);
+
+ setMappings(new ArrayList<Map<Integer, Integer>>());
+
+ //System.out.println("Searching: ");
+ //List overlaps =
UniversalIsomorphismTesterBondTypeInSensitive.getSubgraphAtomsMap(source,
target);
+
+ if ((Molecule1.getAtomCount() == 1) || (Molecule2.getAtomCount() ==
1)) {
+
+ List<CDKRMap> overlaps = CDKMCS.checkSingleAtomCases(Molecule1,
Molecule2);
+ int nAtomsMatched = overlaps.size();
+ nAtomsMatched = (nAtomsMatched > 0) ? 1 : 0;
+ if (nAtomsMatched > 0) {
+ identifySingleAtomsMatchedParts(overlaps, Molecule1,
Molecule2);
+ }
+
+ } else {
+
+ List<List<CDKRMap>> overlaps =
+ CDKMCS.search(Molecule1, Molecule2, new BitSet(), new
BitSet(), true, true, shouldMatchBonds);
+
+ List<List<CDKRMap>> reducedList = removeSubGraph(overlaps);
+ Stack<List<CDKRMap>> allMaxOverlaps = getAllMaximum(reducedList);
+
+ while (!allMaxOverlaps.empty()) {
+ List<List<CDKRMap>> maxOverlapsAtoms =
makeAtomsMapOfBondsMap(allMaxOverlaps.peek(), Molecule1, Molecule2);
+ identifyMatchedParts(maxOverlapsAtoms, Molecule1, Molecule2);
+ allMaxOverlaps.pop();
+ }
+ }
+ FinalMappings.getInstance().set(getMappings());
+ }
+
+ /**
+ * This function calculates only one solution (exact) because we are
looking at the
+ * molecules which are exactly same in terms of the bonds and atoms
determined by the
+ * Fingerprint
+ * @param Molecule1
+ * @param Molecule2
+ * @param shouldMatchBonds
+ * @throws CDKException
+ */
+ public void calculateSubGraphs(IAtomContainer Molecule1, IAtomContainer
Molecule2, boolean shouldMatchBonds) throws CDKException {
+
+ // setSource(Molecule1);
+ // setTarget(Molecule2);
+
+ setMappings(new ArrayList<Map<Integer, Integer>>());
+
+ //System.out.println("Searching: ");
+ //List overlaps =
UniversalIsomorphismTesterBondTypeInSensitive.getSubgraphAtomsMap(source,
target);
+
+ if ((Molecule1.getAtomCount() == 1) || (Molecule2.getAtomCount() ==
1)) {
+
+ List<CDKRMap> overlaps = CDKMCS.checkSingleAtomCases(Molecule1,
Molecule2);
+ int nAtomsMatched = overlaps.size();
+ nAtomsMatched = (nAtomsMatched > 0) ? 1 : 0;
+ if (nAtomsMatched > 0) {
+ identifySingleAtomsMatchedParts(overlaps, Molecule1,
Molecule2);
+ }
+
+ } else {
+
+ List<List<CDKRMap>> overlaps =
+ CDKMCS.getSubgraphMaps(Molecule1, Molecule2,
shouldMatchBonds);
+
+ List<List<CDKRMap>> reducedList = removeSubGraph(overlaps);
+ Stack<List<CDKRMap>> allMaxOverlaps = getAllMaximum(reducedList);
+
+ while (!allMaxOverlaps.empty()) {
+ List<List<CDKRMap>> maxOverlapsAtoms =
makeAtomsMapOfBondsMap(allMaxOverlaps.peek(), Molecule1, Molecule2);
+ identifyMatchedParts(maxOverlapsAtoms, Molecule1, Molecule2);
+ allMaxOverlaps.pop();
+ }
+ }
+ FinalMappings.getInstance().set(getMappings());
+ }
+
+ /**
+ * This function calculates only one solution (exact) because we are
looking at the
+ * molecules which are exactly same in terms of the bonds and atoms
determined by the
+ * Fingerprint
+ * @param Molecule1
+ * @param Molecule2
+ * @param shouldMatchBonds
+ * @throws CDKException
+ */
+ public void calculateIsomorphs(IAtomContainer Molecule1, IAtomContainer
Molecule2, boolean shouldMatchBonds) throws CDKException {
+
+ // setSource(Molecule1);
+ // setTarget(Molecule2);
+
+ setMappings(new ArrayList<Map<Integer, Integer>>());
+
+ //System.out.println("Searching: ");
+ //List overlaps =
UniversalIsomorphismTesterBondTypeInSensitive.getSubgraphAtomsMap(source,
target);
+
+ if ((Molecule1.getAtomCount() == 1) || (Molecule2.getAtomCount() ==
1)) {
+
+ List<CDKRMap> overlaps = CDKMCS.checkSingleAtomCases(Molecule1,
Molecule2);
+ int nAtomsMatched = overlaps.size();
+ nAtomsMatched = (nAtomsMatched > 0) ? 1 : 0;
+ if (nAtomsMatched > 0) {
+ identifySingleAtomsMatchedParts(overlaps, Molecule1,
Molecule2);
+ }
+
+ } else {
+
+ List<List<CDKRMap>> overlaps =
+ CDKMCS.getIsomorphMaps(Molecule1, Molecule2,
shouldMatchBonds);
+
+ List<List<CDKRMap>> reducedList = removeSubGraph(overlaps);
+ Stack<List<CDKRMap>> allMaxOverlaps = getAllMaximum(reducedList);
+
+ while (!allMaxOverlaps.empty()) {
+ List<List<CDKRMap>> maxOverlapsAtoms =
makeAtomsMapOfBondsMap(allMaxOverlaps.peek(), Molecule1, Molecule2);
+ identifyMatchedParts(maxOverlapsAtoms, Molecule1, Molecule2);
+ allMaxOverlaps.pop();
+ }
+ }
+ FinalMappings.getInstance().set(getMappings());
+ }
+
+ /**
+ *
+ * @param overlaps
+ * @return
+ */
+ protected List<List<CDKRMap>> removeSubGraph(List<List<CDKRMap>> overlaps)
{
+
+ List<List<CDKRMap>> reducedList = new
ArrayList<List<CDKRMap>>(overlaps);
+
+ for (int i = 0; i < overlaps.size(); i++) {
+ List<CDKRMap> graphI = overlaps.get(i);
+
+ for (int j = i + 1; j < overlaps.size(); j++) {
+ List<CDKRMap> graphJ = overlaps.get(j);
+
+ // Gi included in Gj or Gj included in Gi then
+ // reduce the irrelevant solution
+ if (graphI.size() != graphJ.size()) {
+ if (isSubgraph(graphJ, graphI)) {
+ reducedList.remove(graphI);
+ } else if (isSubgraph(graphI, graphJ)) {
+ reducedList.remove(graphJ);
+ }
+ }
+
+ }
+ }
+ return reducedList;
+ }
+
+ /**
+ *
+ * @param overlaps
+ * @return
+ */
+ protected List<CDKRMap>
removeRedundantMappingsForSingleAtomCase(List<CDKRMap> overlaps) {
+ List<CDKRMap> reducedList = new ArrayList<CDKRMap>();
+ reducedList.add(overlaps.get(0));
+ //reducedList.add(overlaps.get(1));
+ return reducedList;
+ }
+
+ /**
+ * This makes sourceAtom map of matching atoms out of sourceAtom map of
matching bonds as produced by the get(Subgraph|Ismorphism)Map methods.
+ *
+ * @param rMapList The list produced by the getMap method.
+ * @param graph1 first molecule. Must not be an IQueryAtomContainer.
+ * @param graph2 second molecule. May be an IQueryAtomContainer.
+ * @return The mapping found projected on graph1. This is sourceAtom
List of CDKRMap objects containing Ids of matching atoms.
+ */
+ private List<List<CDKRMap>> makeAtomsMapOfBondsMap(List<CDKRMap> rMapList,
IAtomContainer graph1, IAtomContainer graph2) {
+ if (rMapList == null) {
+ return (null);
+ }
+ List<List<CDKRMap>> result = null;
+ if (rMapList.size() == 1) {
+ result = makeAtomsMapOfBondsMapSingleBond(rMapList, graph1,
graph2);
+ } else {
+ List<CDKRMap> resultLocal = new ArrayList<CDKRMap>();
+ for (int i = 0; i < rMapList.size(); i++) {
+ IBond qBond = graph1.getBond(rMapList.get(i).getId1());
+ IBond tBond = graph2.getBond(rMapList.get(i).getId2());
+ IAtom[] qAtoms = BondManipulator.getAtomArray(qBond);
+ IAtom[] tAtoms = BondManipulator.getAtomArray(tBond);
+ for (int j = 0; j < 2; j++) {
+ List<IBond> bondsConnectedToAtom1j =
graph1.getConnectedBondsList(qAtoms[j]);
+ for (int k = 0; k < bondsConnectedToAtom1j.size(); k++) {
+ if (bondsConnectedToAtom1j.get(k) != qBond) {
+ IBond testBond = bondsConnectedToAtom1j.get(k);
+ for (int m = 0; m < rMapList.size(); m++) {
+ IBond testBond2;
+ if ((rMapList.get(m)).getId1() ==
graph1.getBondNumber(testBond)) {
+ testBond2 =
graph2.getBond((rMapList.get(m)).getId2());
+ for (int n = 0; n < 2; n++) {
+ List<IBond> bondsToTest =
graph2.getConnectedBondsList(tAtoms[n]);
+ if (bondsToTest.contains(testBond2)) {
+ CDKRMap map;
+ if (j == n) {
+ map = new
CDKRMap(graph1.getAtomNumber(qAtoms[0]), graph2.getAtomNumber(tAtoms[0]));
+ } else {
+ map = new
CDKRMap(graph1.getAtomNumber(qAtoms[1]), graph2.getAtomNumber(tAtoms[0]));
+ }
+ if (!resultLocal.contains(map)) {
+ resultLocal.add(map);
+ }
+ CDKRMap map2;
+ if (j == n) {
+ map2 = new
CDKRMap(graph1.getAtomNumber(qAtoms[1]), graph2.getAtomNumber(tAtoms[1]));
+ } else {
+ map2 = new
CDKRMap(graph1.getAtomNumber(qAtoms[0]), graph2.getAtomNumber(tAtoms[1]));
+ }
+ if (!resultLocal.contains(map2)) {
+ resultLocal.add(map2);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ result = new ArrayList<List<CDKRMap>>();
+ result.add(resultLocal);
+ }
+ return result;
+ }
+
+ /**
+ * This makes atom map of matching atoms out of atom map of matching
bonds as produced by the get(Subgraph|Ismorphism)Map methods.
+ * Added by Asad since CDK one doesn't pick up the correct changes
+ * @param list The list produced by the getMap method.
+ * @param sourceGraph first molecule. Must not be an IQueryAtomContainer.
+ * @param targetGraph second molecule. May be an IQueryAtomContainer.
+ * @return The mapping found projected on sourceGraph. This is atom
List of CDKRMap objects containing Ids of matching atoms.
+ */
+ private List<List<CDKRMap>> makeAtomsMapOfBondsMapSingleBond(List<CDKRMap>
list, IAtomContainer sourceGraph, IAtomContainer targetGraph) {
+ if (list == null) {
+ return null;
+ }
+ Map<IBond, IBond> bondMap = new HashMap<IBond, IBond>(list.size());
+ for (CDKRMap solBondMap : list) {
+ int id1 = solBondMap.getId1();
+ int id2 = solBondMap.getId2();
+ IBond qBond = sourceGraph.getBond(id1);
+ IBond tBond = targetGraph.getBond(id2);
+ bondMap.put(qBond, tBond);
+ }
+ List<CDKRMap> result1 = new ArrayList<CDKRMap>();
+ List<CDKRMap> result2 = new ArrayList<CDKRMap>();
+ for (IBond qbond : sourceGraph.bonds()) {
+ if (bondMap.containsKey(qbond)) {
+ IBond tbond = bondMap.get(qbond);
+ CDKRMap map00 = null;
+ CDKRMap map01 = null;
+ CDKRMap map10 = null;
+ CDKRMap map11 = null;
+
+ if
((qbond.getAtom(0).getSymbol().equals(tbond.getAtom(0).getSymbol()))
+ &&
(qbond.getAtom(1).getSymbol().equals(tbond.getAtom(1).getSymbol()))) {
+ map00 = new
CDKRMap(sourceGraph.getAtomNumber(qbond.getAtom(0)),
+ targetGraph.getAtomNumber(tbond.getAtom(0)));
+ map11 = new
CDKRMap(sourceGraph.getAtomNumber(qbond.getAtom(1)),
+ targetGraph.getAtomNumber(tbond.getAtom(1)));
+ if (!result1.contains(map00)) {
+ result1.add(map00);
+ }
+ if (!result1.contains(map11)) {
+ result1.add(map11);
+ }
+ }
+ if
((qbond.getAtom(0).getSymbol().equals(tbond.getAtom(1).getSymbol()))
+ &&
(qbond.getAtom(1).getSymbol().equals(tbond.getAtom(0).getSymbol()))) {
+ map01 = new
CDKRMap(sourceGraph.getAtomNumber(qbond.getAtom(0)),
+ targetGraph.getAtomNumber(tbond.getAtom(1)));
+ map10 = new
CDKRMap(sourceGraph.getAtomNumber(qbond.getAtom(1)),
+ targetGraph.getAtomNumber(tbond.getAtom(0)));
+ if (!result2.contains(map01)) {
+ result2.add(map01);
+ }
+ if (!result2.contains(map10)) {
+ result2.add(map10);
+ }
+ }
+ }
+ }
+ List<List<CDKRMap>> result = new ArrayList<List<CDKRMap>>();
+ if (result1.size() == result2.size()) {
+ result.add(result1);
+ result.add(result2);
+ } else if (result1.size() > result2.size()) {
+ result.add(result1);
+ } else {
+ result.add(result2);
+ }
+ return result;
+ }
+
+ /**
+ *
+ * @param overlaps
+ * @return
+ */
+ protected List getMaximum(List overlaps) {
+ ArrayList list = null;
+ int count = 0;
+ for (Object o : overlaps) {
+ ArrayList arrayList = (ArrayList) o;
+ if (arrayList.size() > count) {
+ list = arrayList;
+ count = arrayList.size();
+ }
+
+ }
+ return list;
+ }
+
+ /**
+ *
+ * @param overlaps
+ * @return
+ */
+ protected Stack<List<CDKRMap>> getAllMaximum(List<List<CDKRMap>> overlaps)
{
+
+ Stack<List<CDKRMap>> allMaximumMappings = null;
+
+ int count = -1;
+
+ for (List<CDKRMap> arrayList : overlaps) {
+ //System.out.println("O size" + sourceAtom.size());
+
+ if (arrayList.size() > count) {
+
+ List<CDKRMap> list = new ArrayList<CDKRMap>(arrayList);
+ count = arrayList.size();
+
+ //System.out.println("List size" + list.size());
+
+ //Collection threadSafeList =
Collections.synchronizedCollection( list );
+ allMaximumMappings = new Stack<List<CDKRMap>>();
+ //allMaximumMappings.clear();
+ allMaximumMappings.push(list);
+ } else if (arrayList.size() == count) {
+
+ List<CDKRMap> list = new ArrayList<CDKRMap>(arrayList);
+ count = arrayList.size();
+ allMaximumMappings.push(list);
+ }
+
+ }
+ return allMaximumMappings;
+ }
+
+ /**
+ *
+ * @param list
+ * @param source
+ * @param target
+ */
+ protected void identifyMatchedParts(List<List<CDKRMap>> list,
IAtomContainer source, IAtomContainer target) {
+
+ List<IAtom> array1 = new ArrayList<IAtom>();
+ List<IAtom> array2 = new ArrayList<IAtom>();
+
+ /*
+ * We have serial numbers of the bonds/Atoms to delete
+ * Now we will collect the actual bond/Atoms rather than
+ * serial number for deletion. RonP flag check whether reactant is
+ * mapped on product or Vise Versa
+ *
+ */
+ for (List<CDKRMap> rMap : list) {
+ Map<Integer, Integer> atomNumbersFromContainer = new
TreeMap<Integer, Integer>();
+ for (CDKRMap rmap : rMap) {
+ IAtom sourceAtom = source.getAtom(rmap.getId1());
+ IAtom targetAtom = target.getAtom(rmap.getId2());
+
+ array1.add(sourceAtom);
+ array2.add(targetAtom);
+
+ int indexI = source.getAtomNumber(sourceAtom);
+ int indexJ = target.getAtomNumber(targetAtom);
+
+ atomNumbersFromContainer.put(indexI, indexJ);
+ }
+ /*Added the Mapping Numbers to the FinalMapping*
+ */
+ getMappings().add(atomNumbersFromContainer);
+ }
+ }
+
+ /**
+ *
+ * @param list
+ * @param source
+ * @param target
+ */
+ protected void identifySingleAtomsMatchedParts(List<CDKRMap> list,
+ IAtomContainer source,
+ IAtomContainer target) {
+
+ List<IAtom> array1 = new ArrayList<IAtom>();
+ List<IAtom> array2 = new ArrayList<IAtom>();
+
+
+
+ /* We have serial numbers of the bonds/Atoms to delete
+ * Now we will collect the actual bond/Atoms rather than
+ * serial number for deletion. RonP flag check whether reactant is
+ * mapped on product or Vise Versa
+ */
+
+ TreeMap<Integer, Integer> atomNumbersFromContainer = new
TreeMap<Integer, Integer>();
+
+ for (CDKRMap rmap : list) {
+ //System.err.print("Map " + o.getClass());
+
+ IAtom sAtom = source.getAtom(rmap.getId1());
+ IAtom tAtom = target.getAtom(rmap.getId2());
+
+ array1.add(sAtom);
+ array2.add(tAtom);
+
+ int indexI = source.getAtomNumber(sAtom);
+ int indexJ = target.getAtomNumber(tAtom);
+
+
+ atomNumbersFromContainer.put(indexI, indexJ);
+
+ /*Added the Mapping Numbers to the FinalMapping*
+ */
+ getMappings().add(atomNumbersFromContainer);
+
+
+ }
+ }
+
+ /**
+ *
+ * @param rmaps1
+ * @param rmaps2
+ * @return
+ */
+ protected boolean isSubgraph(List<CDKRMap> rmaps1, List<CDKRMap> rmaps2) {
+ //System.out.println("Entering isSubgraph.");
+ List<CDKRMap> rmaps2clone = (List<CDKRMap>) ((ArrayList<CDKRMap>)
rmaps2).clone();
+ for (CDKRMap rmap1 : rmaps1) {
+ boolean found = false;
+ for (int i = 0; i < rmaps2clone.size(); ++i) {
+ CDKRMap rmap2 = rmaps2clone.get(i);
+ if (isSameRMap(rmap1, rmap2)) {
+ rmaps2clone.remove(i);
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ return false;
+ }
+
+ }
+ return true;
+ }
+
+ /**
+ *
+ * @param sourceRMap sourceAtom
+ * @param targetRMap targetAtom
+ * @return
+ */
+ protected boolean isSameRMap(CDKRMap sourceRMap, CDKRMap targetRMap) {
+ return sourceRMap.getId1() == targetRMap.getId1()
+ && sourceRMap.getId2() == targetRMap.getId2() ? true : false;
+ }
+
+ /**
+ * Returns mapping solutions
+ * @return the mappings
+ */
+ public List<Map<Integer, Integer>> getMappings() {
+ return mappings;
+ }
+
+ /**
+ * Set mapping solutions
+ * @param mappings the mappings to set
+ */
+ public void setMappings(List<Map<Integer, Integer>> mappings) {
+ this.mappings = mappings;
+ }
+
+ /**
+ * Returns true if a time out occured else false
+ * @return the timeoutFlag
+ */
+ public boolean isTimeoutFlag() {
+ return timeoutFlag;
+ }
+
+ /**
+ * Set time out flag
+ * @param timeoutFlag the timeoutFlag to set
+ */
+ public void setTimeoutFlag(boolean timeoutFlag) {
+ this.timeoutFlag = timeoutFlag;
+ }
+}
Modified:
csplugins/trunk/ucsf/scooter/chemViz/src/chemViz/tasks/CreateMCSSTask.java
===================================================================
--- csplugins/trunk/ucsf/scooter/chemViz/src/chemViz/tasks/CreateMCSSTask.java
2013-02-08 00:28:26 UTC (rev 31113)
+++ csplugins/trunk/ucsf/scooter/chemViz/src/chemViz/tasks/CreateMCSSTask.java
2013-02-09 00:16:32 UTC (rev 31114)
@@ -36,12 +36,16 @@
package chemViz.tasks;
import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
import giny.model.GraphObject;
import giny.view.EdgeView;
@@ -64,10 +68,14 @@
import org.openscience.cdk.Molecule;
import org.openscience.cdk.aromaticity.CDKHueckelAromaticityDetector;
import org.openscience.cdk.exception.CDKException;
+import org.openscience.cdk.interfaces.IAtom;
import org.openscience.cdk.interfaces.IAtomContainer;
import org.openscience.cdk.interfaces.IMolecule;
-import org.openscience.cdk.isomorphism.UniversalIsomorphismTester;
+// import org.openscience.cdk.isomorphism.UniversalIsomorphismTester;
import org.openscience.cdk.smiles.SmilesGenerator;
+import org.openscience.cdk.tools.manipulator.AtomContainerManipulator;
+import org.openscience.cdk.smsd.Isomorphism;
+import org.openscience.cdk.smsd.interfaces.Algorithm;
/**
@@ -140,9 +148,12 @@
int pass = 0;
while (mcssList.size() > 1) {
mcssList = calculateMCSS(mcssList, nThreads);
+ System.out.println("calculateMCSS returns
"+mcssList.size()+" structures");
pass++;
+ if (canceled) break;
}
- mcss = (IMolecule)mcssList.get(0);
+ if (mcssList.size() == 1)
+ mcss = (IMolecule)mcssList.get(0);
calculationComplete = true;
if (showResult) {
@@ -220,26 +231,54 @@
private List<IAtomContainer>
calculateMCSS(List<IAtomContainer>mcssList, int nThreads) {
List<IAtomContainer> newMCSSList =
Collections.synchronizedList(new ArrayList<IAtomContainer>(nThreads));
List<GetMCSSTask> taskList = new ArrayList<GetMCSSTask>();
+ System.out.println("calculateMCSS with "+mcssList.size()+"
structures and "+nThreads+" threads");
+ int taskNumber = 0;
if (nThreads == 1) {
- GetMCSSTask task = new GetMCSSTask(mcssList,
newMCSSList);
+ GetMCSSTask task = new GetMCSSTask(mcssList,
newMCSSList, 1);
task.call();
+ return newMCSSList;
} else {
+ List<Future<IAtomContainer>> futureList = new
ArrayList<Future<IAtomContainer>>();
+ ExecutorService threadPool =
Executors.newFixedThreadPool(nThreads);
int step =
(int)Math.ceil((double)mcssList.size()/(double)nThreads);
if (step < 2) step = 2; // Can't have a step size of
less than 2
for (int i = 0; i < mcssList.size(); i=i+step) {
int endPoint = i+step;
if (endPoint > mcssList.size())
endPoint = mcssList.size();
- taskList.add(new
GetMCSSTask(mcssList.subList(i, endPoint), newMCSSList));
+ List<IAtomContainer> subList = new
ArrayList<IAtomContainer>(mcssList.subList(i, endPoint));
+ System.out.println("Adding
"+subList.size()+"["+i+","+endPoint+"] structures to task list");
+ if (subList.size() > 1)
+ futureList.add(threadPool.submit(new
GetMCSSTask(subList, null, taskNumber++)));
+ else
+ newMCSSList.add(subList.get(0));
}
+ for (Future<IAtomContainer> container: futureList) {
+ if (container == null) continue;
+ try {
+ IAtomContainer f = container.get();
+ if (f != null)
+
newMCSSList.add(container.get());
+ } catch (Exception e) {
+ logger.warning("Execution exception:
"+e);
+ System.out.println("Execution
exception: "+e);
+ e.printStackTrace();
+ }
+ }
+
+ threadPool.shutdown();
+
+/*
ExecutorService threadPool =
Executors.newFixedThreadPool(nThreads);
try {
threadPool.invokeAll(taskList);
} catch (Exception e) {
logger.warning("Execution exception: "+e);
+ System.out.println("Execution exception: "+e);
}
+*/
}
return newMCSSList;
}
@@ -247,31 +286,90 @@
private class GetMCSSTask implements Callable <IAtomContainer> {
List<IAtomContainer> mcssList;
List<IAtomContainer> resultsList;
- IAtomContainer mcss = null;
+ int taskNumber = 0;
+ IAtomContainer innerMcss = null;
- public GetMCSSTask(List<IAtomContainer>mcssList,
List<IAtomContainer>resultsList) {
+ public GetMCSSTask(List<IAtomContainer>mcssList,
List<IAtomContainer>resultsList, int taskNumber) {
this.mcssList = mcssList;
this.resultsList = resultsList;
+ this.taskNumber = taskNumber;
+ mcss = null;
}
- public IAtomContainer call() {
- mcss = mcssList.get(0);
- try {
+ public synchronized IAtomContainer call() {
+ System.out.println("Calling MCSSTask "+taskNumber+"
with "+mcssList.size()+" items");
+ long startTime =
Calendar.getInstance().getTimeInMillis();
+ innerMcss =
AtomContainerManipulator.removeHydrogens(mcssList.get(0));
+
+ long calcTime = startTime;
for (int index = 1; index < mcssList.size();
index++) {
- List<IAtomContainer> overlap =
UniversalIsomorphismTester.getOverlaps(mcss, mcssList.get(index));
- mcss = maximumStructure(overlap);
- if (mcss == null) break;
+ Isomorphism comparison = new
Isomorphism(Algorithm.DEFAULT, true);
+
comparison.setBondSensitiveTimeOut(0.5); // Increase timeout to 30 seconds
+ IAtomContainer target =
AtomContainerManipulator.removeHydrogens(mcssList.get(index));
+ try {
+ System.out.println("mcss for
task "+taskNumber+" has "+innerMcss.getAtomCount()+" atoms, and
"+innerMcss.getBondCount()+" bonds");
+ System.out.println("target for
task "+taskNumber+" has "+target.getAtomCount()+" atoms, and
"+target.getBondCount()+" bonds");
+ System.out.println("comparison
for task "+taskNumber+" is "+comparison);
+ comparison.init(innerMcss,
target, true, true);
+ //
comparison.setChemFilters(true, true, true);
+ innerMcss = getMCSS(comparison);
+ } catch (CDKException e) {
+
System.out.println("CDKException: "+e);
+ e.printStackTrace();
+ logger.warning("CDKException:
"+e);
+ } catch (Exception e) {
+ System.out.println("Exception:
"+e);
+ e.printStackTrace();
+ System.out.println("target has
"+target.getAtomCount()+" atoms");
+ System.out.println("mcss has
"+innerMcss.getAtomCount()+" atoms");
+ logger.warning("Exception: "+e);
+ }
+
+ long endCalcTime =
Calendar.getInstance().getTimeInMillis();
+ System.out.println("Task "+taskNumber+"
index "+index+" took "+(endCalcTime-calcTime)+"ms");
+ calcTime = endCalcTime;
+ if (innerMcss == null || canceled)
break;
}
- } catch (CDKException e) {
- System.out.println("CDKException: "+e);
+ if (resultsList != null)
+ resultsList.add(innerMcss);
+ long endTime = Calendar.getInstance().getTimeInMillis();
+ System.out.println("Done: task "+taskNumber+" took
"+(endTime-startTime)+"ms");
+ return innerMcss;
+ }
+
+ private synchronized IMolecule getMCSS(Isomorphism comparison) {
+ // if (comparison.getAllAtomMapping() == null) return
null;
+ List<IAtomContainer> matchList = new
ArrayList<IAtomContainer>();
+ IAtomContainer mol1 = comparison.getReactantMolecule();
+ // IAtomContainer mol2 =
comparison.getProductMolecule();
+ for (Map<IAtom,IAtom> mapping:
comparison.getAllAtomMapping()) {
+ IAtomContainer match = getMatchedSubgraph(mol1,
mapping);
+ matchList.add(match);
}
- resultsList.add(mcss);
- return mcss;
+ System.out.println("Found "+matchList.size()+"
fragments");
+ return maximumStructure(matchList);
}
+
+ private synchronized IAtomContainer
getMatchedSubgraph(IAtomContainer container, Map<IAtom, IAtom> matches) {
+ IAtomContainer needle =
container.getBuilder().newInstance(IAtomContainer.class, container);
+ // Every atom in our structure that *doesn't* have an
entry in the matches map should be removed
+ List<IAtom> atomListToBeRemoved = new
ArrayList<IAtom>();
+ for (IAtom containerAtom : container.atoms()) {
+ if (!matches.containsKey(containerAtom)) {
+ int index =
container.getAtomNumber(containerAtom);
+
atomListToBeRemoved.add(needle.getAtom(index));
+ }
+ }
+ for (IAtom removeAtom : atomListToBeRemoved) {
+
needle.removeAtomAndConnectedElectronContainers(removeAtom);
+ }
+ return needle;
+ }
- private IMolecule maximumStructure(List<IAtomContainer>
mcsslist) {
+ private synchronized IMolecule
maximumStructure(List<IAtomContainer> mcsslist) {
int maxmcss = -99999999;
IAtomContainer maxac = null;
+ int fragment = 1;
if (mcsslist == null || mcsslist.size() == 0) return
null;
for (IAtomContainer a: mcsslist) {
if (a.getAtomCount() > maxmcss) {
@@ -283,10 +381,10 @@
}
public IAtomContainer get() {
- if (mcss == null)
+ if (innerMcss == null)
return call();
else
- return mcss;
+ return innerMcss;
}
}
}
--
You received this message because you are subscribed to the Google Groups
"cytoscape-cvs" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/cytoscape-cvs?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.