af270c2063531eae92b567b9faeeac2c338e3fd6
[jalview.git] / src / jalview / ext / archaeopteryx / ArchaeopteryxTreeBuilder.java
1 package jalview.ext.archaeopteryx;
2
3 import jalview.analysis.TreeBuilder;
4 import jalview.datamodel.SequenceI;
5 import jalview.ext.forester.ForesterDataConversions;
6 import jalview.ext.forester.ForesterMatrix;
7 import jalview.util.MessageManager;
8
9 import java.util.HashMap;
10 import java.util.Map;
11
12 import org.forester.evoinference.matrix.distance.DistanceMatrix;
13 import org.forester.phylogeny.Phylogeny;
14 import org.forester.phylogeny.PhylogenyNode;
15 import org.forester.phylogeny.data.NodeData;
16 import org.forester.phylogeny.data.Sequence;
17
18 /**
19  * Class for converting trees made in Jalview (through TreeBuilder) to trees
20  * compatible with Forester (Phylogeny objects).
21  * 
22  * Note that this currently demands a 1:1 relationship between tree nodes and
23  * the sequences used for generating them.
24  * 
25  * @author kjvanderheide
26  *
27  */
28 public class ArchaeopteryxTreeBuilder
29         implements ExternalTreeBuilderI<Phylogeny, PhylogenyNode>
30 {
31   protected final SequenceI[] sequences;
32
33   protected final DistanceMatrix distances;
34   
35   protected final TreeBuilder jalviewTree;
36   
37   public String treeTitle;
38
39   private final Phylogeny aptxTree;
40
41   private PhylogenyNode rootNode;
42
43   private final Map<SequenceI, PhylogenyNode> alignmentBoundNodes;
44
45   private final Map<PhylogenyNode, SequenceI> nodesBoundAlignment;
46
47   public ArchaeopteryxTreeBuilder(final TreeBuilder calculatedTree)
48   {
49     jalviewTree = calculatedTree;
50     sequences = jalviewTree.getSequences();
51     distances = ForesterMatrix.convertJalviewToForester(
52             jalviewTree.getDistances(), sequences);
53     aptxTree = new Phylogeny();
54     rootNode = new PhylogenyNode();
55     alignmentBoundNodes = new HashMap<>(distances.getSize());
56     nodesBoundAlignment = new HashMap<>(distances.getSize());
57
58
59   }
60
61   @Override
62   public Phylogeny buildTree(final PhylogenyNode treeRoot)
63   {
64
65     if (treeRoot != null)
66     {
67       rootNode = treeRoot;
68     }
69
70     buildTree();
71
72     return aptxTree;
73
74   }
75
76
77   @Override
78   public Phylogeny buildTree()
79   {
80
81     for (SequenceI sequence : sequences)
82     {
83       Sequence seq = ForesterDataConversions
84               .createForesterSequence(sequence, true);
85       PhylogenyNode sequenceNode = new PhylogenyNode(sequence.getName());
86       NodeData nodeData = sequenceNode.getNodeData();
87       nodeData.setSequence(seq);
88
89       nodesBoundAlignment.put(sequenceNode, sequence);
90       alignmentBoundNodes.put(sequence, sequenceNode);
91       rootNode.addAsChild(sequenceNode);
92     }
93
94
95     aptxTree.setRoot(rootNode);
96
97     treeTitle = generateTreeName();
98     aptxTree.setName(treeTitle);
99
100     return aptxTree;
101
102   }
103
104   @Override
105   public Map<SequenceI, PhylogenyNode> getAlignmentBoundNodes()
106   {
107     return alignmentBoundNodes;
108   }
109
110   @Override
111   public Map<PhylogenyNode, SequenceI> getNodesBoundAlignment()
112   {
113     return nodesBoundAlignment;
114   }
115
116   private Phylogeny clusterNodes()
117   {
118     return aptxTree;
119
120   }
121   /**
122    * Formats a localised title for the tree panel, like
123    * <p>
124    * Neighbour Joining Using BLOSUM62
125    * <p>
126    * For a tree loaded from file, just uses the file name
127    * 
128    * @return
129    */
130   @Override
131   public String generateTreeName() // Move this and add selection region to the
132                                    // title when applicable
133   {
134     if (treeTitle != null) // will currently never happen, loaded tree file will
135                            // take a different path
136     {
137       return treeTitle;
138     }
139     else
140     {
141       /*
142       * i18n description of Neighbour Joining or Average Distance method
143       */
144       String treecalcnm = MessageManager
145               .getString("label.tree_calc_" + jalviewTree.getClass()
146                       .getSimpleName().substring(0, 2).toLowerCase());
147       /*
148       * short score model name (long description can be too long)
149       */
150       String smn = jalviewTree.getScoreModel().getName();
151
152       /*
153       * put them together as <method> Using <model>
154       */
155       final String ttl = MessageManager
156               .formatMessage("label.treecalc_title", treecalcnm, smn);
157       return ttl;
158     }
159   }
160 }