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.


Reply via email to