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