1 package jalview.ext.archaeopteryx;
3 import jalview.datamodel.SequenceI;
4 import jalview.ext.treeviewer.TreeNodeI;
7 import java.util.ArrayList;
8 import java.util.HashMap;
12 import org.forester.phylogeny.PhylogenyMethods;
13 import org.forester.phylogeny.PhylogenyNode;
14 import org.forester.phylogeny.data.BranchColor;
16 public class TreeNode implements TreeNodeI
18 private final PhylogenyNode node;
20 private SequenceI nodeSeq;
22 private static Map<PhylogenyNode, TreeNodeI> originalNodes = new HashMap<>(
23 500); // prolly make this size dynamic
25 private static Map<TreeNodeI, PhylogenyNode> wrappedNodes = new HashMap<>(
28 private TreeNode(PhylogenyNode aptxNode)
31 originalNodes.put(aptxNode, this);
32 wrappedNodes.put(this, aptxNode);
38 public String getNodeName()
40 return node.getName();
45 public List<TreeNodeI> getAllDescendants()
48 List<PhylogenyNode> descNodes = PhylogenyMethods
49 .getAllDescendants(node);
50 return getUniqueWrappers(descNodes);
56 public List<TreeNodeI> getExternalDescendants()
58 List<PhylogenyNode> extDescNodes = node.getAllExternalDescendants();
59 return getUniqueWrappers(extDescNodes);
64 public List<TreeNodeI> getDirectChildren()
66 List<PhylogenyNode> childNodes = node.getDescendants();
67 return getUniqueWrappers(childNodes);
75 public void setSequence(SequenceI seq)
78 org.forester.phylogeny.data.Sequence foresterFormatSeq = DataConversions
79 .createForesterSequence(seq, true);
80 node.getNodeData().setSequence(foresterFormatSeq);
85 public SequenceI getSequence()
88 // ideally this would return a converted node.getNodeData().getSequence()
92 public void addAsChild(TreeNodeI childNode)
94 PhylogenyNode aptxNode = unwrapNode(childNode);
96 node.addAsChild(aptxNode);
107 public float getXcoord()
109 return node.getXcoord();
113 public void setBranchColor(Color branchColor)
115 node.getBranchData().setBranchColor(new BranchColor(branchColor));
120 public boolean isInternal()
122 return node.isInternal();
125 public static List<TreeNodeI> getUniqueWrappers(
126 List<PhylogenyNode> aptxNodes)
128 List<TreeNodeI> wrappedNodes = new ArrayList<>(
131 for (PhylogenyNode aptxNode : aptxNodes)
133 wrappedNodes.add(getUniqueWrapper(aptxNode));
139 * This method should be used to create new wrappers as there is a possibility
140 * the Archaeopteryx node was already introduced to Jalview previously so this
141 * avoids giving one node duplicate wrappers
146 public static TreeNodeI getUniqueWrapper(
147 PhylogenyNode aptxNode)
149 if (aptxNode == null)
153 TreeNodeI wrappedNode = originalNodes.get(aptxNode);
154 if (wrappedNode == null)
156 wrappedNode = new TreeNode(aptxNode);
162 * Attempts to unwrap the given node, if the unwrapped node already exists it
163 * is simply returned as is. If it is not however, the wrapper will be used to
164 * create a new Archaeopteryx node. This way it becomes possible to construct
165 * new Archaeopteryx nodes from different tree viewers, as long as they
166 * implement the interface.
171 protected static PhylogenyNode unwrapNode(TreeNodeI wrappedNode)
173 if (wrappedNode == null)
177 PhylogenyNode aptxNode = wrappedNodes.get(wrappedNode);
178 if (aptxNode == null)
181 aptxNode = new PhylogenyNode(wrappedNode.getNodeName());
190 public int hashCode()
192 final int prime = 31;
194 result = (int) (prime * result
195 + ((node == null) ? 0 : (node.hashCode() * getId())));
200 public boolean equals(Object obj)
210 if (getClass() != obj.getClass())
214 TreeNode other = (TreeNode) obj;
217 if (other.node != null)
222 if (getId() != other.getId())
227 if (!node.equals(other.node))
236 public float getYcoord()
238 return node.getYcoord();