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 nodeSeq = DataConversions
33 .createJalviewSequence(aptxNode.getNodeData().getSequence());
34 originalNodes.put(aptxNode, this);
35 wrappedNodes.put(this, aptxNode);
41 public String getNodeName()
43 return node.getName();
48 public List<TreeNodeI> getAllDescendants()
51 List<PhylogenyNode> descNodes = PhylogenyMethods
52 .getAllDescendants(node);
53 return getUniqueWrappers(descNodes);
59 public List<TreeNodeI> getExternalDescendants()
61 List<PhylogenyNode> extDescNodes = node.getAllExternalDescendants();
62 return getUniqueWrappers(extDescNodes);
67 public List<TreeNodeI> getDirectChildren()
69 List<PhylogenyNode> childNodes = node.getDescendants();
70 return getUniqueWrappers(childNodes);
78 public void setSequence(SequenceI seq)
81 org.forester.phylogeny.data.Sequence foresterFormatSeq = DataConversions
82 .createForesterSequence(seq, true);
83 node.getNodeData().setSequence(foresterFormatSeq);
88 public SequenceI getSequence()
91 // ideally this would return a converted node.getNodeData().getSequence()
95 public void addAsChild(TreeNodeI childNode)
97 PhylogenyNode aptxNode = unwrapNode(childNode);
99 node.addAsChild(aptxNode);
110 public float getXcoord()
112 return node.getXcoord();
116 public void setBranchColor(Color branchColor)
118 node.getBranchData().setBranchColor(new BranchColor(branchColor));
123 public boolean isInternal()
125 return node.isInternal();
128 public static List<TreeNodeI> getUniqueWrappers(
129 List<PhylogenyNode> aptxNodes)
131 List<TreeNodeI> wrappedNodes = new ArrayList<>(
134 for (PhylogenyNode aptxNode : aptxNodes)
136 wrappedNodes.add(getUniqueWrapper(aptxNode));
142 * This method should be used to create new wrappers as there is a possibility
143 * the Archaeopteryx node was already introduced to Jalview previously so this
144 * avoids giving one node duplicate wrappers
149 public static TreeNodeI getUniqueWrapper(
150 PhylogenyNode aptxNode)
152 if (aptxNode == null)
156 TreeNodeI wrappedNode = originalNodes.get(aptxNode);
157 if (wrappedNode == null)
159 wrappedNode = new TreeNode(aptxNode);
165 * Attempts to unwrap the given node, if the unwrapped node already exists it
166 * is simply returned as is. If it is not however, the wrapper will be used to
167 * create a new Archaeopteryx node. This way it becomes possible to construct
168 * new Archaeopteryx nodes from different tree viewers, as long as they
169 * implement the interface.
174 protected static PhylogenyNode unwrapNode(TreeNodeI wrappedNode)
176 if (wrappedNode == null)
180 PhylogenyNode aptxNode = wrappedNodes.get(wrappedNode);
181 if (aptxNode == null)
184 aptxNode = new PhylogenyNode(wrappedNode.getNodeName());
193 public int hashCode()
195 final int prime = 31;
197 result = (int) (prime * result
198 + ((node == null) ? 0 : (node.hashCode() * getId())));
203 public boolean equals(Object obj)
213 if (getClass() != obj.getClass())
217 TreeNode other = (TreeNode) obj;
220 if (other.node != null)
225 if (getId() != other.getId())
230 if (!node.equals(other.node))
239 public float getYcoord()
241 return node.getYcoord();