Package org.cytoscape.ClusterViz.internal.algorithm

Source Code of org.cytoscape.ClusterViz.internal.algorithm.FAGEC

package org.cytoscape.ClusterViz.internal.algorithm;

import org.cytoscape.ClusterViz.internal.Cluster;
import org.cytoscape.ClusterViz.internal.ClusterGraph;
import org.cytoscape.ClusterViz.internal.ClusterUtil;
import org.cytoscape.ClusterViz.internal.ParameterSet;
import org.cytoscape.ClusterViz.internal.algorithm.Algorithm.NodeInfo;
import org.cytoscape.model.CyNetwork;
import org.cytoscape.work.TaskMonitor;
import org.cytoscape.model.CyNode;
import org.cytoscape.model.CyEdge;

import java.util.*;



public class FAGEC extends Algorithm{


  public FAGEC(Long networkID,ClusterUtil clusterUtil){
    super(networkID, clusterUtil);
  }
 

  /**
     * FAG-EC Algorithm Step 1:
     * Calculate arc weights which is defined as
     * ( sizOf(Ni Intersect Nj) +1 )/ min[(ki),(kj)]
     *
     * @param inputNetwork The network that will be calculated
     */   
    public void calEdgeWeight(CyNetwork inputNetwork){
        String callerID = "In Algorithm.calEdgeWeight";
      Long networkID=inputNetwork.getSUID();
      if(!edgeWeightNetworkMap.containsKey(networkID)){
            double weight;
            int degree1,degree2,min;
            ArrayList al;
          TreeMap edgeWeightsMap=new TreeMap(new Comparator(){
            //sort Doubles in descending order
            public int compare(Object o1,Object o2){
              double d1=((Double)o1).doubleValue();
              double d2=((Double)o2).doubleValue();
              if(d1==d2){
                return 0;
              }
              else if(d1<d2){
                return 1;
              }
              else return -1;
            }
          });     
          Iterator edges=inputNetwork.getEdgeList().iterator();
          while(edges.hasNext()&&!cancelled){  //for each edge, cal the weight
            weight=0.0;
            int common=0;
            CyEdge e=(CyEdge)edges.next();
            Long nFrom=e.getSource().getSUID();
            Long nTo=e.getTarget().getSUID();
           
            //cal the edge weght
           
            List<CyNode> listneighbors1 = inputNetwork.getNeighborList(inputNetwork.getNode(nFrom), CyEdge.Type.ANY);
            List<CyNode> listneighbors2 = inputNetwork.getNeighborList(inputNetwork.getNode(nTo), CyEdge.Type.ANY);

           
           
            // Get neighborhood of this node (including the node)
/*           
            if (listneighbors1.size() < 2) {
              // If there are no neighbors or just one neighbor, nodeInfo calculation is trivial
              NodeInfo nodeInfo = new NodeInfo();

              if (listneighbors1.size() == 1) {
                nodeInfo.coreLevel = 1;
                nodeInfo.coreDensity = 1.0;
                nodeInfo.density = 1.0;
              }

              return nodeInfo;
            }*/

            Long[] neighbors1 = new Long[listneighbors1.size()];
            int i = 0;

            for (CyNode n : listneighbors1) {
              neighbors1[i++] = n.getSUID();
            }

            // Add original node to extract complete neighborhood
            Arrays.sort(neighbors1);
           
           
//           Long[] neighbors1=getNeighborArray(inputNetwork,nFrom);
//          Long[] neighbors2=getNeighborArray(inputNetwork,nTo);
            Arrays.sort(neighbors1);
            for(int j=0;j<listneighbors2.size();j++){
              Long key=listneighbors2.get(j).getSUID();
              if(Arrays.binarySearch(neighbors1, key)>=0)//exist a common neighbor of both nodes
                common++;
            }
            common++;
            degree1 = inputNetwork.getAdjacentEdgeList(e.getSource(), CyEdge.Type.ANY).size();
            degree2 = inputNetwork.getAdjacentEdgeList(e.getTarget(), CyEdge.Type.ANY).size();

//            degree1=super.getNodeDegree(inputNetwork,e.getSource().getSUID());
//            degree2=getNodeDegree(inputNetwork,e.getTarget().getSUID());
           
           
/*            degree1=inputNetwork.getDegree(e.getSource());
            degree2=inputNetwork.getDegree(e.getTarget());*/
            min=degree1<degree2 ? degree1:degree2;
            weight=(double)(common)/(double)min;
           
            //add to the edge weights map
            if(edgeWeightsMap.containsKey(new Double(weight))) {
              al=(ArrayList)edgeWeightsMap.get(new Double(weight));
              al.add(e.getSUID());
            }else{
              al=new ArrayList();
              al.add(e.getSUID());
              edgeWeightsMap.put(new Double(weight), al);
            }
          }        
          curEdgeWeights=edgeWeightsMap;
          edgeWeightNetworkMap.put(networkID, edgeWeightsMap);
      }
      else{
        curEdgeWeights=(TreeMap)edgeWeightNetworkMap.get(networkID);
      }
    }

   /**
     * FAG-EC Algorithm Step 2 Generate complexes:
     * @param inputNetwork The input network
     * @param resultTitle Title of the result, used as an identifier in various hash maps
     * @return the clusters identified
     */
   public List<Cluster> FAG_ECFinder(CyNetwork inputNetwork,int resultTitle){
        String callerID = "Algorithm.FAG_ECFinder";
      System.out.println("In "+callerID);
      params=getParams();

      currentNetwork=inputNetwork;
      calNodeInfos(inputNetwork);
        calEdgeWeight(inputNetwork);
        if (curEdgeWeights == null || curNodeInfos==null) {
            System.err.println("In " + callerID + ": nodeInfos Map or edgeWeights Map was null.");
            return (null);
        }
        long msTimeBefore = System.currentTimeMillis();
        int findingProgress = 0;
        int findingTotal = 0;
        Collection values = curEdgeWeights.values(); //returns a Collection sorted by key order (descending)
        for (Iterator i1 = values.iterator(); i1.hasNext();) {
            ArrayList value = (ArrayList) i1.next();
            for(Iterator i2 = value.iterator(); i2.hasNext();) {
                i2.next();
                findingTotal++;
            }
        }
        //stores the list of clusters as ArrayLists of node indices in the input Network
        ArrayList alOriginalClusters = new ArrayList(inputNetwork.getNodeCount());
        /************************First, we sort each single node into a clique*************************/
        int i=0;
        Iterator nodes = inputNetwork.getNodeList().iterator();
        while(nodes.hasNext()){
          CyNode n=(CyNode) nodes.next();
         
         
          int degree = inputNetwork.getAdjacentEdgeList(n, CyEdge.Type.ANY).size();

          //int degree=super.getNodeDegree(inputNetwork,n.getSUID());
        //int degree=inputNetwork.getDegree(n);
        Cluster newCluster = new Cluster(i);
        ArrayList alNodes=new ArrayList();
        alNodes.add(n.getSUID());
       
        newCluster.setAlCluster(alNodes);
//        newCluster.setALNodes(alNodes);
        newCluster.setTotalDegree(degree);
        Long nodeIndex= n.getSUID();
        ((NodeInfo)curNodeInfos.get(nodeIndex)).setComplex(i);
        i++;
        alOriginalClusters.add(newCluster);
        }
        /**********************************************************************************************
      Then, Operation UNION:  according to different situation, in which the two nodes consisting
        this arc may belong to different Complexes or an identical Complex and that the
        attributes of the Complexes varies, we take on different action
         ***********************************************************************************************/
        ArrayList alEdgeWithSameWeight; 
        CyEdge curEdge;                                                                                                                         
        for (Iterator iterator = values.iterator(); iterator.hasNext();) {
            //each weight may be associated with multiple edges, iterate over these lists
          alEdgeWithSameWeight = (ArrayList) iterator.next();
            for (int j = 0; j < alEdgeWithSameWeight.size(); j++) {//for each edge
                Long edgeIndex = ((Long) alEdgeWithSameWeight.get(j)).longValue();
                curEdge=inputNetwork.getEdge(edgeIndex);               
            Long inFrom = curEdge.getSource().getSUID();
            Long inTo   = curEdge.getTarget().getSUID();
            NodeInfo fromNI=(NodeInfo)curNodeInfos.get(inFrom)//source node info
            NodeInfo toNI=(NodeInfo)curNodeInfos.get(inTo)//target node info
           
            int icFrom=fromNI.iComplex;  //complex that the source node belongs to
            int icTo=toNI.iComplex;    //complex that the target node belongs to
            if(icFrom != icTo)    //we have take some actions only if the two complexes are not the same
            {
              Cluster cFrom=(Cluster)alOriginalClusters.get(icFrom);
              Cluster cTo=(Cluster)alOriginalClusters.get(icTo);
              if(cFrom.isMergeable() && cTo.isMergeable())  //the two complexes are both mergeable
                if(!cFrom.isModule() || !cTo.isModule())  //either of the two complexes are not modules yet
                  //if(cFrom.getALNodes().size() >= cTo.getALNodes().size()){//merge the smaller complexe to the larger one
                  if(cFrom.getALCluster().size() >= cTo.getALCluster().size()){//merge the smaller complexe to the larger one
                    if(params.isWeak()) mergeComplexes1(cFrom, cTo);
                    else  mergeComplexes2(cFrom, cTo);  
                  }
                  else//merge the smaller complex to the larger one
                    if(params.isWeak())  mergeComplexes1(cTo, cFrom);
                    else  mergeComplexes2(cFrom, cTo);
                  }
                else  //both of the two complexes are modules
                {
                  cFrom.setMergeable(false);
                  cTo.setMergeable(false);
                }
              else  //either of the two complexes is not mergeable
              {
                cFrom.setMergeable(false);
              cTo.setMergeable(false);
              }
            }
                if (taskMonitor != null) {
                    findingProgress++;
                    //We want to be sure that only progress changes are reported and not
                    //miniscule decimal increments so that the taskMonitor isn't overwhelmed
                    int newProgress = (findingProgress * 100) / findingTotal;
                    int oldProgress = ((findingProgress-1) * 100) / findingTotal;
                    if (newProgress != oldProgress) {
                        taskMonitor.setProgress(newProgress);
                    }
                }
                if (cancelled) {
                    break;
                }
            }
        }
        ArrayList alClusters = new ArrayList();
        Iterator it=alOriginalClusters.iterator();
        while(it.hasNext()){
          Cluster cluster=(Cluster)it.next();
//          if(cluster.getALNodes().size()>=params.getComplexSizeThreshold()){

          if(cluster.getALCluster().size()>=params.getComplexSizeThreshold()){
            //
            //ArrayList<Long> alNodes=cluster.getALNodes();
            List<Long> alNodes=cluster.getALCluster();
            ClusterGraph gpCluster = this.createClusterGraph(alNodes, inputNetwork);
            //cluster.setComplexID(counter++);
            cluster.setGraph(gpCluster);
            cluster.setScore(0.0);
            cluster.setSeedNode(alNodes.get(0));
           
//            cluster.setResultTitle(resultTitle);
            cluster.setResultTitle(resultTitle);
            int ind=cluster.getInDegree();
            int outd=cluster.getTotalDegree()-2*ind;
            if(ind!=0 && outd!=0)
              cluster.setModularity((double)ind/(double)outd);
            else
                cluster.calModularity(inputNetwork,this);
            alClusters.add(cluster);
          }
        }
        //Once the clusters have been found we either return them or in the case of selection scope,
        //we select only the ones that contain the selected node(s) and return those
        ArrayList selectedALClusters = new ArrayList();
        if (!params.getScope().equals(ParameterSet.NETWORK)) {
            for (Iterator ic = alClusters.iterator(); ic.hasNext();){
                Cluster cluster = (Cluster) ic.next();
                List<Long> alNodes = cluster.getALCluster();
                ArrayList alSelectedNodes = new ArrayList();
                for (int c = 0; c < params.getSelectedNodes().length; c++) {
                    alSelectedNodes.add(params.getSelectedNodes()[c]);
                }
                //method for returning all clusters that contain any of the selected nodes
                boolean hit = false;
                for (Iterator in = alSelectedNodes.iterator(); in.hasNext();) {
                    if (alNodes.contains((Long) in.next())) {
                        hit = true;
                    }
                }
                if (hit) {
                    selectedALClusters.add(cluster);
                }
            }
            alClusters = selectedALClusters;
        }
        //Finally convert the arraylist into a fixed array
/*        Cluster[] clusters = new Cluster[alClusters.size()];
        for (int c = 0; c < clusters.length; c++) {
            clusters[c] = (Cluster) alClusters.get(c);
        }*/
        long msTimeAfter = System.currentTimeMillis();
        lastFindTime = msTimeAfter - msTimeBefore;
        return alClusters;
    }

    /**
     * merge two unoverlapped complexes ,weak definition
     */
    protected void mergeComplexes1(Cluster c1,Cluster c2){
      int inDegree=c1.getInDegree();
      int totalDegree=c1.getTotalDegree()+c2.getTotalDegree();
     
      List<Long> alNodes=c1.getALCluster();
      Iterator i=c2.getALCluster().iterator();

     
//      ArrayList alNodes=c1.getALNodes();
//      Iterator i=c2.getALNodes().iterator();
     
     
     
      while(i.hasNext()){
        Long nodeIndex=((Long)i.next()).longValue();
        Long[] adjs=getNeighborArray(currentNetwork,nodeIndex);
        for(int j=0;j<adjs.length;j++)
          if(alNodes.contains(adjs[j]))
              inDegree++;
        alNodes.add(nodeIndex);
        NodeInfo node=(NodeInfo)curNodeInfos.get(nodeIndex);
        node.setComplex(c1.getResultId());
        //node.setComplex(c1.getComplexID());
      }
      c1.setInDegree(inDegree);
      c1.setTotalDegree(totalDegree);
      int outDegree=totalDegree-2*inDegree;
      if(outDegree<0)
        System.err.println("Error outDegree!");
      float fModule = (float)inDegree/(float)(outDegree);
      if( fModule>params.getfThreshold() )
        c1.setModule(true);
      c2.getALCluster().clear();
    }
    /**
     * merge two unoverlapped complexes ,strong definition
     */
    protected void mergeComplexes2(Cluster c1,Cluster c2){
      List<Long> alNodes=c1.getALCluster();
      Iterator i=c2.getALCluster().iterator();
      while(i.hasNext()){
        Long nodeIndex=((Long)i.next()).longValue();
        NodeInfo node=(NodeInfo)curNodeInfos.get(new Long(nodeIndex));
        node.setComplex(c1.getResultId());
        alNodes.add(new Long(nodeIndex));
      }
      c2.getALCluster().clear();
      i=alNodes.iterator();
      c1.setModule(true);
      int nodeInDegree,nodeTotalDegree;
      while(i.hasNext()){
        Long nodeIndex=((Long)i.next()).longValue();
        Long[] adjs=getNeighborArray(currentNetwork,nodeIndex);
        nodeInDegree=0;
        for(int j=0;j<adjs.length;j++)
          if(alNodes.contains(adjs[j]))
              nodeInDegree++;
       
       
        nodeTotalDegree = currentNetwork.getAdjacentEdgeList(currentNetwork.getNode(nodeIndex), CyEdge.Type.ANY).size();

//        nodeTotalDegree=super.getNodeDegree(currentNetwork,nodeIndex);
        //nodeTotalDegree=currentNetwork.getDegree(nodeIndex);
          double fModule = (double)nodeInDegree/(double)(nodeTotalDegree);
        if(fModule<0.5)
          c1.setModule(false);
      }
    }
    /**
     * merge overlapped complexes with weak module definition
     */
    protected void mergeComplexes3(Cluster c1, Cluster c2){
      List<Long> nodes1=c1.getALCluster();
      List<Long> nodes2=c2.getALCluster();
      //add the unoverlapped nodes and set the subComplexes of all nodes in C2
      NodeInfo nodeNI;
      ArrayList subComplexes;
      for(Iterator it=nodes2.iterator();it.hasNext();){//for each node in C2
        Long node=(Long)it.next();
        nodeNI=(NodeInfo)curNodeInfos.get(node);
        subComplexes=nodeNI.getAlComplex();
        if(!nodes1.contains(node)){//this is not a overlapped node
            int index=subComplexes.indexOf(new Integer(c2.getResultId()));
            subComplexes.remove(index);
            subComplexes.add(new Integer(c1.getResultId()));
          nodes1.add(node);
        }
        else//this node already exists in C1
            int index=subComplexes.indexOf(new Integer(c2.getResultId()));
            subComplexes.remove(index);
        }
      }
      //calculate the other informations for C1
      int inDegree=0;
      int totalDegree=0;
      for(Iterator it=nodes1.iterator();it.hasNext();){//for each node in merged C1
        Long node=((Long)it.next()).longValue();
       
        totalDegree+= currentNetwork.getAdjacentEdgeList(currentNetwork.getNode(node), CyEdge.Type.ANY).size();

//        totalDegree+=super.getNodeDegree(currentNetwork,node);
        //totalDegree+=currentNetwork.getDegree(node);//can this be useful?
        Long[] neighbors=getNeighborArray(currentNetwork,node);
        for(int i=0;i<neighbors.length;i++)
          if(nodes1.contains(neighbors[i]))
            inDegree++;
      }
      int outDegree=totalDegree-inDegree;
      inDegree=inDegree/2;
      c1.setInDegree(inDegree);
      c1.setTotalDegree(totalDegree);
      double fModule = (double)inDegree/(double)outDegree;
      if(fModule>params.getfThreshold())
        c1.setModule(true);
      //clear the content of nodes2
      nodes2.clear();
    }
    /**
     * merge overlapped complexes using strong module definition
     */
    protected void mergeComplexes4(Cluster c1, Cluster c2){
      List<Long> nodes1=c1.getALCluster();
      List<Long> nodes2=c2.getALCluster();
      //add the unoverlapped nodes and set the subComplexes of all nodes in C2
      NodeInfo nodeNI;
      ArrayList subComplexes;
      for(Iterator it=nodes2.iterator();it.hasNext();){//for each node in C2
        Long node=(Long)it.next();
        nodeNI=(NodeInfo)curNodeInfos.get(node);
        subComplexes=nodeNI.getAlComplex();
        if(!nodes1.contains(node)){//this is not a overlapped node
            int index=subComplexes.indexOf(new Integer(c2.getResultId()));
            subComplexes.remove(index);
            subComplexes.add(new Integer(c1.getResultId()));
          nodes1.add(node);
        }
        else//this node already exists in C1
            int index=subComplexes.indexOf(new Integer(c2.getResultId()));
            subComplexes.remove(index);
        }
      }
      c1.setModule(true);
      int nodeInDegree,nodeTotalDegree;
      for(Iterator i=nodes1.iterator();i.hasNext();){
        Long nodeIndex=((Long)i.next()).longValue();
        Long[] adjs=getNeighborArray(currentNetwork,nodeIndex);
        nodeInDegree=0;
        for(int j=0;j<adjs.length;j++)
          if(nodes1.contains(adjs[j]))
              nodeInDegree++;
       
       
        nodeTotalDegree=super.getNodeDegree(currentNetwork,nodeIndex);
//       nodeTotalDegree=currentNetwork.getDegree(nodeIndex);
          float fModule = (float)nodeInDegree/(float)(nodeTotalDegree);
        if(fModule<0.5){
          c1.setModule(false);
        }
      }
      //clear the content of nodes2
      nodes2.clear();
    }


  /**
     * EAGLE Step1 and FEA-EC Step2(optional) get Maximal Cliques:
     * get all the maximal cliques in the network
     * @param inputNetwork the operated network
     */
    public void getMaximalCliques(CyNetwork inputNetwork,int resultTitle){
        String callerID = "Algorithm.getMaximalCliques";
        long startTime=System.currentTimeMillis();
        if (inputNetwork == null) {
            System.err.println("In " + callerID + ": inputNetwork was null.");
            return;
        }
      currentNetwork=inputNetwork;
      params=getParams();

    Long net=inputNetwork.getSUID();
      if(!maximalCliquesNetworkMap.containsKey(inputNetwork.getSUID())){
        System.out.println("Get MaximalCliques for This Network........");
            long msTimeBefore = System.currentTimeMillis();
        HashMap cliques = new HashMap();
       
          //initialize states
        Vector alCur=new Vector();
        Vector alFini=new Vector();
        Vector alNodes=new Vector(inputNetwork.getNodeCount());
        for(Iterator i=inputNetwork.getNodeList().iterator();i.hasNext();){
          Long node=new Long(((CyNode)i.next()).getSUID());
          alNodes.add(node);
        }       
        //The critical internal process
        expand(cliques,alCur,alNodes,alFini);
       
        curCliques=cliques;
        maximalCliquesNetworkMap.put(net, cliques);
        findCliquesTime=System.currentTimeMillis()-msTimeBefore;
      }
      else
        curCliques=(HashMap)maximalCliquesNetworkMap.get(net);
      findCliquesTime=System.currentTimeMillis()-startTime;
    }
   
    @Override
  public List<Cluster> run(CyNetwork inputNetwork, int resultTitle){
     return(this.FAG_ECFinder(inputNetwork, resultTitle));
  }

}
TOP

Related Classes of org.cytoscape.ClusterViz.internal.algorithm.FAGEC

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.