/******************************************************************************* * Copyright (C) 2017 Philipp Spohr * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. ******************************************************************************/ package de.hhu.ba.yoshikoWrapper.graphModel; import java.util.ArrayList; import java.util.HashMap; import org.cytoscape.model.CyEdge; import org.cytoscape.model.CyNetwork; import org.cytoscape.model.CyNode; import org.cytoscape.model.subnetwork.CySubNetwork; import org.cytoscape.view.layout.CyLayoutAlgorithm; import org.cytoscape.view.model.CyNetworkView; import org.cytoscape.view.presentation.property.BasicVisualLexicon; import org.cytoscape.view.vizmap.VisualStyle; import org.cytoscape.view.vizmap.mappings.ContinuousMapping; import de.hhu.ba.yoshikoWrapper.core.CyCore; import de.hhu.ba.yoshikoWrapper.core.LocalizationManager; public class YoshikoSolution { private CyNetwork originalGraph; public ArrayList<YoshikoCluster> cluster; public int id; public YoshikoSolution(CyNetwork originalGraph) { cluster = new ArrayList<YoshikoCluster>(); this.originalGraph = originalGraph; } /** * Transforms this solution in a meta-graph where each cluster is represented by one node * The nodes are linked to subgraphs representing the cluster and also their size is scaled relative to cluster size */ public void exportMetaGraph() { CyNetwork metaGraph = CyCore.networkFactory.createNetwork(); metaGraph.getRow(metaGraph).set(CyNetwork.NAME, LocalizationManager.get("metaGraph")); metaGraph.getDefaultNodeTable().createColumn("clusterSize", Integer.class, false); metaGraph.getDefaultEdgeTable().createColumn("edgeStrength", Integer.class, false); CyLayoutAlgorithm layout = CyCore.layoutAlgorithmManager.getDefaultLayout(); //Map Cluster to Nodes for further reference HashMap<YoshikoCluster,CyNode> map = new HashMap<YoshikoCluster,CyNode>(); //Add nodes for (YoshikoCluster c: cluster) { CyNode clusterNode = metaGraph.addNode(); CySubNetwork subnet = c.getSubNetwork(); CyCore.networkManager.addNetwork(subnet); //Create network view and register it CyNetworkView subnetView = CyCore.networkViewFactory.createNetworkView(subnet); CyCore.networkViewManager.addNetworkView(subnetView); //layout cluster CyCore.dialogTaskManager.execute( layout.createTaskIterator( subnetView, layout.getDefaultLayoutContext(), CyLayoutAlgorithm.ALL_NODE_VIEWS, null ) ); VisualStyle vs= CyCore.visualStyleFactory.createVisualStyle(CyCore.visualMappingManager.getCurrentVisualStyle()); CyCore.visualMappingManager.setVisualStyle(vs, subnetView); vs.apply(subnetView); clusterNode.setNetworkPointer(subnet); //Set node attributes metaGraph.getRow(clusterNode).set("name", LocalizationManager.get("cluster")+" "+c.getID()); metaGraph.getRow(clusterNode).set("clusterSize",c.getSize()); map.put(c, clusterNode); } //Add edges (O(|C|^2*|V|^2) can maybe be improved? //TODO for (YoshikoCluster c1:cluster) { for (YoshikoCluster c2:cluster) { if ( metaGraph.containsEdge(map.get(c1),map.get(c2)) || c1 == c2 ) { continue; } for (CyNode c1n : c1.getSubNetwork().getNodeList()) { for (CyNode c2n : c2.getSubNetwork().getNodeList()) { if (originalGraph.containsEdge(c1n, c2n) || originalGraph.containsEdge(c2n, c1n)) { if (metaGraph.containsEdge(map.get(c1), map.get(c2))){ //TODO: Update weight } else { CyEdge edge = metaGraph.addEdge(map.get(c1), map.get(c2), false); metaGraph.getRow(edge).set("edgeStrength",1); } } } } } } CyNetworkView view = CyCore.networkViewFactory.createNetworkView(metaGraph); //layout solution CyCore.dialogTaskManager.execute( layout.createTaskIterator( view, layout.getDefaultLayoutContext(), CyLayoutAlgorithm.ALL_NODE_VIEWS, null ) ); CyCore.networkManager.addNetwork(metaGraph); CyCore.networkViewManager.addNetworkView( view ); //define style for solution ContinuousMapping<Integer, Double> contMap = (ContinuousMapping<Integer, Double>)CyCore.continuousMappingFactory.createVisualMappingFunction( "clusterSize", Integer.class, BasicVisualLexicon.NODE_SIZE ); VisualStyle vs= CyCore.visualStyleFactory.createVisualStyle(CyCore.visualMappingManager.getCurrentVisualStyle()); vs.addVisualMappingFunction(contMap); CyCore.visualMappingManager.addVisualStyle(vs); CyCore.cy.setCurrentNetworkView(view); //Apply visual style CyCore.visualMappingManager.setVisualStyle(vs, view); vs.apply(view); view.updateView(); } }