/* * #%L * gitools-core * %% * Copyright (C) 2013 Universitat Pompeu Fabra - Biomedical Genomics group * %% * 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 3 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. 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, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ /******************************************************************************* * Copyright 2013 Lars Behnke * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package org.gitools.heatmap.header; import com.google.common.base.Joiner; import com.google.common.base.Strings; import org.gitools.api.analysis.Clusters; import javax.xml.bind.annotation.*; import java.util.*; @XmlAccessorType(XmlAccessType.FIELD) @XmlType(propOrder = {"name", "sortName", "parentName", "leaves", "distance", "weight", "color", "children"}) public class HierarchicalCluster implements Clusters, Comparable<HierarchicalCluster> { private String name; private String sortName; private String parentName; private int leaves; private Double distance; private Double weight = 0.0; private int color; @XmlElementWrapper(name = "children") @XmlElement(name = "child") private List<HierarchicalCluster> children; public HierarchicalCluster() { //JAXB requirement } public HierarchicalCluster(String... identifiers) { leaves = identifiers.length; if (identifiers.length == 1) { name = identifiers[0]; } } public HierarchicalCluster(Set<String> leftIds, Set<String> rightIds) { leaves = leftIds.size() + rightIds.size(); } public Double getDistance() { return distance; } public void setDistance(Double distance) { this.distance = distance; } public List<HierarchicalCluster> getChildren() { if (children == null) { children = new ArrayList<>(); } return children; } public void setChildren(List<HierarchicalCluster> children) { this.children = children; } public void setParent(HierarchicalCluster parent) { this.parentName = parent.getName(); } public Set<String> getIdentifiers(Set<String> idSet) { if (isLeaf()) { idSet.add(name); } else { for (HierarchicalCluster child : children) { child.getIdentifiers(idSet); } } return idSet; } public Map<String, String> getMaxLevel(Map<String, String> idSet) { if (isLeaf()) { idSet.put(name, sortName == null ? parentName : sortName ); } else { for (HierarchicalCluster child : children) { child.getMaxLevel(idSet); } } return idSet; } public Set<String> getIdentifiers() { return getIdentifiers(getIdentifiers(new HashSet<String>())); } public String getName() { return name; } public void setName(String name) { this.name = name; for (HierarchicalCluster child : children) { child.setParentName(name); } } public String getSortName() { return sortName; } public void setSortName(String sortName) { this.sortName = sortName; } public void addChild(HierarchicalCluster cluster) { getChildren().add(cluster); } public Double getWeight() { return weight; } public void setWeight(Double weight) { this.weight = (weight == null ? 0.0 : weight); } public boolean contains(HierarchicalCluster cluster) { return getChildren().contains(cluster); } @Override public String toString() { return name + "-" + leaves; } public boolean isLeaf() { return leaves == 1 || children == null || children.size() == 0; } public int countLeafs() { return countLeafs(this, 0); } public int countLeafs(HierarchicalCluster node, int count) { if (node.isLeaf()) count++; for (HierarchicalCluster child : node.getChildren()) { count += child.countLeafs(); } return count; } public void toConsole(int indent) { for (int i = 0; i < indent; i++) { System.out.print(" "); } String name = Joiner.on('&').join(getIdentifiers()) + (isLeaf() ? " (leaf)" : "") + (distance != null ? " distance: " + distance : ""); System.out.println(name); for (HierarchicalCluster child : getChildren()) { child.toConsole(indent + 1); } } public double getTotalDistance() { double dist = getDistance() == null ? 0 : getDistance(); if (getChildren().size() > 0) { dist += children.get(0).getTotalDistance(); } return dist; } public int getLeaves() { return leaves; } public void setLeaves(int leaves) { this.leaves = leaves; } public int getColor() { return color; } public void setColor(int color) { this.color = color; } @Override public Collection<String> getClusters() { throw new UnsupportedOperationException(); } @Override public Set<String> getItems(String cluster) { throw new UnsupportedOperationException(); } @Override public Map<String, Set<String>> getClustersMap() { throw new UnsupportedOperationException(); } @Override public int compareTo(HierarchicalCluster o) { int result; if (o == null || o.getWeight() == null) { result = -1; } else if (getWeight() == null) { result = 1; } else { Double w1 = getWeight() / leaves; Double w2 = o.getWeight() / o.getIdentifiers().size(); result = w1.compareTo(w2); } return result; } public String getParentName() { return parentName; } public void setParentName(String parentName) { this.parentName = parentName; } public HierarchicalCluster getHierarchicalSubCluster(String clusterName) { HierarchicalCluster foundCluster = null; if (Strings.isNullOrEmpty(clusterName)) { return this; } for (HierarchicalCluster cluster : this.getChildren()) { if (cluster.getName().equals(clusterName)) { foundCluster = cluster; break; } } if (foundCluster == null) { for (HierarchicalCluster cluster : this.getChildren()) { foundCluster = cluster.getHierarchicalSubCluster(clusterName); if (foundCluster != null) { break; } } } return foundCluster; } }