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