Merge branch 'kjvdh/features/PhylogenyViewer_tabbedsupport' into merge/2_11_2/kjvdh...
[jalview.git] / src / jalview / ext / archaeopteryx / AptxTreeBuilder.java
diff --git a/src/jalview/ext/archaeopteryx/AptxTreeBuilder.java b/src/jalview/ext/archaeopteryx/AptxTreeBuilder.java
new file mode 100644 (file)
index 0000000..74d89d2
--- /dev/null
@@ -0,0 +1,170 @@
+package jalview.ext.archaeopteryx;
+
+import jalview.analysis.TreeBuilder;
+import jalview.datamodel.SequenceI;
+import jalview.ext.forester.DataConversions;
+import jalview.ext.forester.ForesterMatrix;
+import jalview.ext.treeviewer.ExternalTreeBuilderI;
+import jalview.util.MappingUtils;
+import jalview.util.MessageManager;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.forester.evoinference.matrix.distance.DistanceMatrix;
+import org.forester.phylogeny.Phylogeny;
+import org.forester.phylogeny.PhylogenyNode;
+import org.forester.phylogeny.data.NodeData;
+import org.forester.phylogeny.data.Sequence;
+
+/**
+ * Class for converting trees made in Jalview (through TreeBuilder) to trees
+ * compatible with Forester (Phylogeny objects).
+ * 
+ * Note that this currently demands a 1:1 relationship between tree nodes and
+ * the sequences used for generating them.
+ * 
+ * @author kjvanderheide
+ *
+ */
+public class AptxTreeBuilder
+        implements ExternalTreeBuilderI<Phylogeny, PhylogenyNode>
+{
+  protected final SequenceI[] sequences;
+
+  protected final DistanceMatrix distances;
+  
+  protected final TreeBuilder jalviewTree;
+  
+  public String treeTitle;
+
+  private final Phylogeny aptxTree;
+
+  private PhylogenyNode rootNode;
+
+  private final Map<SequenceI, PhylogenyNode> alignmentWithNodes;
+
+  private final Map<PhylogenyNode, SequenceI> nodesWithAlignment;
+
+  public AptxTreeBuilder(final TreeBuilder calculatedTree)
+  {
+    jalviewTree = calculatedTree;
+    sequences = jalviewTree.getSequences();
+    distances = ForesterMatrix.convertJalviewToForester(
+            jalviewTree.getDistances(), sequences);
+
+    aptxTree = new Phylogeny();
+    rootNode = new PhylogenyNode();
+
+    int amountOfSequences = distances.getSize();
+    alignmentWithNodes = new HashMap<>(amountOfSequences);
+    nodesWithAlignment = new HashMap<>(amountOfSequences);
+
+
+  }
+
+  @Override
+  public Phylogeny buildTree(final PhylogenyNode treeRoot)
+  {
+
+    if (treeRoot != null)
+    {
+      rootNode = treeRoot;
+    }
+
+    buildTree();
+
+    return aptxTree;
+
+  }
+
+
+  @Override
+  public Phylogeny buildTree()
+  {
+
+    for (SequenceI sequence : sequences)
+    {
+      Sequence seq = DataConversions
+              .createForesterSequence(sequence, true);
+      PhylogenyNode sequenceNode = new PhylogenyNode(sequence.getName());
+
+      NodeData nodeData = sequenceNode.getNodeData();
+      nodeData.setSequence(seq);
+
+      MappingUtils.putWithDuplicationCheck(nodesWithAlignment,
+              sequenceNode, sequence);
+      MappingUtils.putWithDuplicationCheck(alignmentWithNodes,
+              sequence, sequenceNode);
+      rootNode.addAsChild(sequenceNode);
+    }
+
+
+    aptxTree.setRoot(rootNode);
+
+    treeTitle = generateTreeName();
+    aptxTree.setName(treeTitle);
+
+    return aptxTree;
+
+  }
+
+  @Override
+  public Map<SequenceI, PhylogenyNode> getAlignmentBoundNodes()
+  {
+    return alignmentWithNodes;
+  }
+
+  @Override
+  public Map<PhylogenyNode, SequenceI> getNodesBoundAlignment()
+  {
+    return nodesWithAlignment;
+  }
+
+  private Phylogeny clusterNodes()
+  {
+    return aptxTree;
+
+  }
+  /**
+   * Formats a localised title for the tree panel, like
+   * <p>
+   * Neighbour Joining Using BLOSUM62
+   * <p>
+   * For a tree loaded from file, just uses the file name
+   * 
+   * @return
+   */
+  @Override
+  public String generateTreeName() // Move this and add selection region to the
+                                   // title when applicable
+  {
+    if (treeTitle != null) // will currently never happen, loaded tree file will
+                           // take a different path
+    {
+      return treeTitle;
+    }
+    else
+    {
+      /*
+      * i18n description of Neighbour Joining or Average Distance method
+      */
+      String treecalcnm = MessageManager
+              .getString("label.tree_calc_" + jalviewTree.getClass()
+                      .getSimpleName().substring(0, 2).toLowerCase());
+      /*
+      * short score model name (long description can be too long)
+      */
+      String smn = jalviewTree.getScoreModel().getName();
+
+      /*
+      * put them together as <method> Using <model>
+      */
+      final String ttl = MessageManager
+              .formatMessage("label.treecalc_title", treecalcnm, smn);
+      return ttl;
+    }
+  }
+  
+
+}