Package BiNGO.BiNGO

Source Code of BiNGO.BiNGO.NodeDistances$NodeDistancesTask

package BiNGO.BiNGO ;

// redistributed Cytoscape code

/* * Redistributed Date: Mar.25.2005
* * by : Steven Maere
* * Copyright (c) 2005 Flanders Interuniversitary Institute for Biotechnology (VIB)
* *
* * This program is free software; you can redistribute it and/or modify
* * it under the terms of the GNU General Public License as published by
* * the Free Software Foundation; either version 2 of the License, or
* * (at your option) any later version.
* *
* * 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.
* * The software and documentation provided hereunder is on an "as is" basis,
* * and the Flanders Interuniversitary Institute for Biotechnology
* * has no obligations to provide maintenance, support,
* * updates, enhancements or modifications.  In no event shall the
* * Flanders Interuniversitary Institute for Biotechnology
* * be liable to any party for direct, indirect, special,
* * incidental or consequential damages, including lost profits, arising
* * out of the use of this software and its documentation, even if
* * the Flanders Interuniversitary Institute for Biotechnology
* * has been advised of the possibility of such damage. See the
* * GNU General Public License for more details.
* *
* * You should have received a copy of the GNU General Public License
* * along with this program; if not, write to the Free Software
* * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
* */

import org.cytoscape.work.Task;
import org.cytoscape.work.TaskMonitor;
/*import giny.model.GraphPerspective;*/
import org.cytoscape.model.CyNode;
import java.io.PrintStream;
import java.util.*;
import java.util.concurrent.ExecutionException;
import javax.swing.SwingWorker;
import org.cytoscape.model.*;
import java.util.*;

/**
* Calculates the all-pairs-shortest-paths (APSP) of a set of <code>giny.model.Node</code>
* objects that reside in a <code>giny.model.GraphPerspective</code>.
* Note: this was copied from giny.util because it is being phased out.  Eventually
* the layout API will be available to use (TODO: remove when layout API is available)
*
* @see giny.util.IntNodeDistances
*/
public class NodeDistances implements MonitorableTask{

    public static final int INFINITY = Integer.MAX_VALUE;

    protected List nodesList;
    /*protected GraphPerspective perspective;*/
    protected CyNetwork network;
    protected int[][] distances;
    protected boolean directed;

    // Keep track of progress for monitoring:
    private int maxValue;
    private TaskMonitor taskMonitor = null;
    private boolean interrupted = false;
   
  protected int currentProgress;
  protected int lengthOfTask;
  protected String statusMessage;
  protected boolean done;
  protected boolean canceled;

    protected Map nodeIndexToMatrixIndexMap; //a root node index to matrix index map

   
    class NodeDistancesTask
  {

    final NodeDistances this$0;

    NodeDistancesTask()
    {
      this$0 = NodeDistances.this;
      //super();
      calculate();
    }
  }

    /**
     * Constructor, defaults to undirected graph.
     *
     * @param nodes_list  a <code>List</code> of <code>giny.model.Node</code> objects for
     *                    which distances will be calculated
     * @param distances   the 2 dimensional array that will hold the calculated distances
     *                    (possibly null)
     * @param perspective the <code>giny.model.GraphPerspective</code> in which the nodes
     *                    reside
     * @deprecated Can't use this now that GraphPerspective uses root graph indices.
     */
   
    public NodeDistances(List nodesList, CyNetwork network, Map nodeIndexToMatrixIndexMap)
  {
    this.nodesList = nodesList;
    this.nodeIndexToMatrixIndexMap =  nodeIndexToMatrixIndexMap;
    this.network = network;
    distances = new int[nodesList.size()][];
    directed = false;
  }
   
/*    public NodeDistances(List nodes_list, int[][] distances, GraphPerspective perspective) {
        this(nodes_list, distances, perspective, false);

    }//NodeDistances
*/
    /**
     * Constructor, specifies whether a the graph should be treated as a directed graph or not.
     *
     * @param nodes_list  a <code>List</code> of <code>giny.model.Node</code> objects for
     *                    which distances will be calculated
     * @param distances   the 2 dimensional array that will hold the calculated distances
     *                    (possibly null)
     * @param perspective the <code>giny.model.GraphPerspective</code> in which the nodes
     *                    reside
     * @param directed    if <code>true</code>, then APSP is calculated assuming a directed graph,
     *                    if <code>false</code> an undirected graph is assumed
     * @deprecated Can't use this now that GraphPerspective uses root graph indices.
     */
/*    public NodeDistances(List nodes_list,
                         int[][] distances,
                         GraphPerspective perspective,
                         boolean directed) {
        this.perspective = perspective;
        nodesList = nodes_list;
        if (distances == null) {
            this.distances = new int[nodesList.size()][];
        } else {
            this.distances = distances;
        }
        this.directed = directed;
    }//NodeDistances
*/
    /**
     * The main constructor
     *
     * @param nodesList                 List of nodes ordered by the index map
     * @param perspective               The <code>giny.model.GraphPerspective</code> in which the nodes reside
     * @param nodeIndexToMatrixIndexMap An index map that maps your root graph indices to the returned matrix indices
     */
/*    public NodeDistances(List nodesList, GraphPerspective perspective, HashMap nodeIndexToMatrixIndexMap) {
        this.nodesList = nodesList;
        this.nodeIndexToMatrixIndexMap = nodeIndexToMatrixIndexMap;
        this.perspective = perspective;
        this.distances = new int[nodesList.size()][];
        this.directed = false;
    }
*/
    /**
     * Calculates the node distances.
     *
     * @return the <code>int[][]</code> array of calculated distances or null if the
     *         task was canceled or there was an error
     */
    public int[][] calculate() {
        int currentProgress = 0;
        this.maxValue = distances.length;

        CyNode[] nodes = new CyNode[nodesList.size()];

        // TODO: REMOVE
        // System.err.println( "Calculating all node distances.. for: "
        //+nodesList.size()+" and "+nodes.length );

        // We don't have to make new Integers all the time, so we store the index
        // Objects in this array for reuse.
        Integer[] integers = new Integer[nodes.length];

        // Fill the nodes array with the nodes in their proper index locations.
        //int index;
        CyNode from_node;

        for (int i = 0; i < nodes.length; i++) {

            from_node = (CyNode) nodesList.get(i);
            if (from_node == null) {
                continue;
            }
            int index = ((Integer)nodeIndexToMatrixIndexMap.get(from_node.getSUID())).intValue();
            //index = ((Integer) nodeIndexToMatrixIndexMap.get(new Integer(from_node.getRootGraphIndex()))).intValue();

            if ((index < 0) || (index >= nodes.length)) {
                System.err.println("WARNING: GraphNode \"" + from_node +
                        "\" has an index value that is out of range: " +
                        index +
                        ".  Graph indices should be maintained such " +
                        "that no index is unused.");
                return null;
            }
            if (nodes[index] != null) {
                System.err.println("WARNING: GraphNode \"" + from_node +
                        "\" has an index value ( " + index + " ) that is the same as " +
                        "that of another GraphNode ( \"" + nodes[index] +
                        "\" ).  Graph indices should be maintained such " +
                        "that indices are unique.");
                return null;
            }
            nodes[index] = from_node;
            Integer in = new Integer(index);
            integers[index] = in;
        }

        LinkedList queue = new LinkedList();
        boolean[] completed_nodes = new boolean[nodes.length];
        Iterator neighbors;
        CyNode to_node;
        CyNode neighbor;
        int neighbor_index;
        int to_node_distance;
        int neighbor_distance;
        for (int from_node_index = 0;
             from_node_index < nodes.length;
             from_node_index++) {

            if (this.interrupted) {
                // The task was canceled
                this.distances = null;
                return this.distances;
            }

            from_node = nodes[from_node_index];

            if (from_node == null) {
                // Make the distances in this row all Integer.MAX_VALUE.
                if (distances[from_node_index] == null) {
                    distances[from_node_index] = new int[nodes.length];
                }
                Arrays.fill(distances[from_node_index], Integer.MAX_VALUE);
                continue;
            }

            // TODO: REMOVE
            //  System.err.print( "Calculating node distances from graph node " +
            //                  from_node );
            //System.err.flush();

            // Make the distances row and initialize it.
            if (distances[from_node_index] == null) {
                distances[from_node_index] = new int[nodes.length];
            }
            Arrays.fill(distances[from_node_index], Integer.MAX_VALUE);
            distances[from_node_index][from_node_index] = 0;

            // Reset the completed nodes array.
            Arrays.fill(completed_nodes, false);

            // Add the start node to the queue.
            queue.add(integers[from_node_index]);

            while (!(queue.isEmpty())) {

                if (this.interrupted) {
                    // The task was canceled
                    this.distances = null;
                    return this.distances;
                }

                int index = ((Integer) queue.removeFirst()).intValue();
                if (completed_nodes[index]) {
                    continue;
                }
                completed_nodes[index] = true;

                to_node = nodes[index];
                to_node_distance = distances[from_node_index][index];

                if (index < from_node_index) {
                    // Oh boy.  We've already got every distance from/to this node.
                    int distance_through_to_node;
                    for (int i = 0; i < nodes.length; i++) {
                        if (distances[index][i] == Integer.MAX_VALUE) {
                            continue;
                        }
                        distance_through_to_node =
                                to_node_distance + distances[index][i];
                        if (distance_through_to_node <=
                                distances[from_node_index][i]) {
                            // Any immediate neighbor of a node that's already been
                            // calculated for that does not already have a shorter path
                            // calculated from from_node never will, and is thus complete.
                            if (distances[index][i] == 1) {
                                completed_nodes[i] = true;
                            }
                            distances[from_node_index][i] =
                                    distance_through_to_node;
                        }
                    } // End for every node, update the distance using the distance from
                    // to_node.
                    // So now we don't need to put any neighbors on the queue or
                    // anything, since they've already been taken care of by the previous
                    // calculation.
                    continue;
                } // End if to_node has already had all of its distances calculated.

                neighbors = getNeighbors(to_node).iterator();
               
                //neighbors = perspective.neighborsList(to_node).iterator();

                while (neighbors.hasNext()) {

                    if (this.interrupted) {
                        this.distances = null;
                        return this.distances;
                    }

                    neighbor = (CyNode) neighbors.next();

                   
                    neighbor_index = ((Integer)nodeIndexToMatrixIndexMap.get(neighbor.getSUID())).intValue();
                   
                    //neighbor_index = ((Integer) nodeIndexToMatrixIndexMap.get(new Integer(neighbor.getRootGraphIndex()))).intValue();

                    // If this neighbor was not in the incoming List, we cannot include
                    // it in any paths.
                    if (nodes[neighbor_index] == null) {
                        distances[from_node_index][neighbor_index] =
                                Integer.MAX_VALUE;
                        continue;
                    }

                    if (completed_nodes[neighbor_index]) {
                        // We've already done everything we can here.
                        continue;
                    }

                    neighbor_distance = distances[from_node_index][neighbor_index];

                    if ((to_node_distance != Integer.MAX_VALUE) &&
                            (neighbor_distance > (to_node_distance + 1))) {
                        distances[from_node_index][neighbor_index] =
                                (to_node_distance + 1);
                        queue.addLast(integers[neighbor_index]);
                    }

                    // TODO: REMOVE
                    //System.out.print( "." );
                    //System.out.flush();


                } // For each of the next nodes' neighbors
                // TODO: REMOVE
                //System.out.print( "|" );
                //System.out.flush();
            } // For each to_node, in order of their (present) distances

            // TODO: REMOVE
            /*
            System.err.println( "done." );
            */
            // Calculate Percentage.  This must be a value between 0..100.
            int percentComplete = (int) (((double) currentProgress / maxValue) * 100);

            //  Estimate Time Remaining
            long timeRemaining = maxValue - currentProgress;

            //  Update the Task Monitor.
            //  This automatically updates the UI Component w/ progress bar.
            if (taskMonitor != null) {
                taskMonitor.setProgress(percentComplete);
                taskMonitor.setStatusMessage("Calculating Node Distances: " + currentProgress + "of " + maxValue);
               // taskMonitor.setEstimatedTimeRemaining(timeRemaining);
            }

            currentProgress++;

        } // For each from_node

        // TODO: REMOVE
        //System.err.println( "..Done calculating all node distances." );

        return distances;
    }//calculate

    /**
     * @return the <code>int[][]</code> 2D array of calculated distances or null
     *         if not yet calculated
     */
    public int[][] getDistances() {
        return this.distances;
    }//getDistances

    /**
     * Run the Task.
     */
    public void run() {
        calculate();
    }

    /**
     * Non-blocking call to interrupt the task.
     */
    public void halt() {
        this.interrupted = true;
    }

    /**
     * Sets the Task Monitor.
     *
     * @param taskMonitor TaskMonitor Object.
     */
    public void setTaskMonitor(TaskMonitor taskMonitor) {
        if (this.taskMonitor != null) {
            throw new IllegalStateException("Task Monitor is already set.");
        }
        this.taskMonitor = taskMonitor;
    }

    /**
     * Gets the Task Title.
     *
     * @return human readable task title.
     */
    public String getTitle() {
        return new String("Calculating Node Distances");
    }

  public boolean wasCanceled()
  {
    return canceled;
  }

  public int getCurrentProgress()
  {
    return currentProgress;
  }

  public int getLengthOfTask()
  {
    return lengthOfTask;
  }

  public String getTaskDescription()
  {
    return "Calculating Node Distances";
  }

  public String getCurrentStatusMessage()
  {
    return statusMessage;
  }

  public boolean isDone()
  {
    return done;
  }

  public void stop()
  {
    canceled = true;
    statusMessage = null;
  }

 
  public void start(boolean return_when_done) {
    // TODO Auto-generated method stub
    SwingWorker worker = new SwingWorker() {

      final NodeDistances this$0;

      protected Object doInBackground()
        throws Exception
      {
        return new NodeDistancesTask();
      }

     
      {
        this$0 = NodeDistances.this;
        //super();
      }
    };
    worker.execute();
    if (return_when_done)
      try
      {
        worker.get();
      }
      catch (InterruptedException e)
      {
        e.printStackTrace();
      }
      catch (ExecutionException e)
      {
        e.printStackTrace();
      }
  }


 
 
  private Collection getNeighbors(CyNode node)
  {
    Set result = new HashSet();
    Collection edges = network.getAdjacentEdgeList(node, org.cytoscape.model.CyEdge.Type.ANY);
    if (edges == null || edges.size() == 0)
      return result;
    Long targetID = node.getSUID();
    for (Iterator iterator = edges.iterator(); iterator.hasNext();)
    {
      CyEdge curEdge = (CyEdge)iterator.next();
      if (curEdge.getSource().getSUID() != targetID)
        result.add(curEdge.getSource());
      else
      if (curEdge.getTarget().getSUID() != targetID)
        result.add(curEdge.getTarget());
    }

    return result;
  }

} // class NodeDistances
TOP

Related Classes of BiNGO.BiNGO.NodeDistances$NodeDistancesTask

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.