1 package jalview.ext.archaeopteryx;
3 import jalview.datamodel.SequenceI;
4 import jalview.ext.forester.DataConversions;
5 import jalview.ext.treeviewer.TreeNodeI;
8 import java.util.ArrayList;
9 import java.util.HashMap;
10 import java.util.List;
13 import org.forester.phylogeny.PhylogenyMethods;
14 import org.forester.phylogeny.PhylogenyNode;
15 import org.forester.phylogeny.data.BranchColor;
17 public class TreeNode implements TreeNodeI
19 private final PhylogenyNode node;
21 private SequenceI nodeSeq;
23 private static Map<PhylogenyNode, TreeNodeI> originalNodes = new HashMap<>(
24 500); // prolly make this size dynamic
26 private static Map<TreeNodeI, PhylogenyNode> wrappedNodes = new HashMap<>(
29 private TreeNode(PhylogenyNode aptxNode)
32 if (aptxNode.getNodeData().getSequence() != null)
34 nodeSeq = DataConversions
35 .createJalviewSequence(aptxNode);
37 originalNodes.put(aptxNode, this);
38 wrappedNodes.put(this, aptxNode);
44 public String getNodeName()
46 return node.getName();
51 public List<TreeNodeI> getAllDescendants()
54 List<PhylogenyNode> descNodes = PhylogenyMethods
55 .getAllDescendants(node);
56 return getUniqueWrappers(descNodes);
62 public List<TreeNodeI> getExternalDescendants()
64 List<PhylogenyNode> extDescNodes = node.getAllExternalDescendants();
65 return getUniqueWrappers(extDescNodes);
70 public List<TreeNodeI> getDirectChildren()
72 List<PhylogenyNode> childNodes = node.getDescendants();
73 return getUniqueWrappers(childNodes);
81 public void setSequence(SequenceI seq)
84 org.forester.phylogeny.data.Sequence foresterFormatSeq = DataConversions
85 .createForesterSequence(seq, true);
86 node.getNodeData().setSequence(foresterFormatSeq);
91 public SequenceI getSequence()
97 public void addAsChild(TreeNodeI childNode)
99 PhylogenyNode aptxNode = unwrapNode(childNode);
101 node.addAsChild(aptxNode);
112 public float getXcoord()
114 return node.getXcoord();
118 public void setBranchColor(Color branchColor)
120 node.getBranchData().setBranchColor(new BranchColor(branchColor));
125 public boolean isInternal()
127 return node.isInternal();
130 public static List<TreeNodeI> getUniqueWrappers(
131 List<PhylogenyNode> aptxNodes)
133 List<TreeNodeI> wrappedNodes = new ArrayList<>(
136 for (PhylogenyNode aptxNode : aptxNodes)
138 wrappedNodes.add(getUniqueWrapper(aptxNode));
144 * This method should be used to create new wrappers as there is a possibility
145 * the Archaeopteryx node was already introduced to Jalview previously so this
146 * avoids giving one node duplicate wrappers
151 public static TreeNodeI getUniqueWrapper(
152 PhylogenyNode aptxNode)
154 if (aptxNode == null)
158 TreeNodeI wrappedNode = originalNodes.get(aptxNode);
159 if (wrappedNode == null)
161 wrappedNode = new TreeNode(aptxNode);
167 * Attempts to unwrap the given node, if the unwrapped node already exists it
168 * is simply returned as is. If it is not however, the wrapper will be used to
169 * create a new Archaeopteryx node. This way it becomes possible to construct
170 * new Archaeopteryx nodes from different tree viewers, as long as they
171 * implement the interface.
176 protected static PhylogenyNode unwrapNode(TreeNodeI wrappedNode)
178 if (wrappedNode == null)
182 PhylogenyNode aptxNode = wrappedNodes.get(wrappedNode);
183 if (aptxNode == null)
186 aptxNode = new PhylogenyNode(wrappedNode.getNodeName());
195 public int hashCode()
197 final int prime = 31;
199 result = (int) (prime * result
200 + ((node == null) ? 0 : (node.hashCode() * getId())));
205 public boolean equals(Object obj)
215 if (getClass() != obj.getClass())
219 TreeNode other = (TreeNode) obj;
222 if (other.node != null)
227 if (getId() != other.getId())
232 if (!node.equals(other.node))
241 public float getYcoord()
243 return node.getYcoord();