Class |
Line # |
Actions |
|||
---|---|---|---|---|---|
TreeBuilder | 40 | 53 | 18 |
1 | /* | |
2 | * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) | |
3 | * Copyright (C) $$Year-Rel$$ The Jalview Authors | |
4 | * | |
5 | * This file is part of Jalview. | |
6 | * | |
7 | * Jalview is free software: you can redistribute it and/or | |
8 | * modify it under the terms of the GNU General Public License | |
9 | * as published by the Free Software Foundation, either version 3 | |
10 | * of the License, or (at your option) any later version. | |
11 | * | |
12 | * Jalview is distributed in the hope that it will be useful, but | |
13 | * WITHOUT ANY WARRANTY; without even the implied warranty | |
14 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR | |
15 | * PURPOSE. See the GNU General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License | |
18 | * along with Jalview. If not, see <http://www.gnu.org/licenses/>. | |
19 | * The Jalview Authors are detailed in the 'AUTHORS' file. | |
20 | */ | |
21 | package jalview.analysis; | |
22 | ||
23 | import jalview.api.analysis.ScoreModelI; | |
24 | import jalview.api.analysis.SimilarityParamsI; | |
25 | import jalview.datamodel.AlignmentAnnotation; | |
26 | import jalview.datamodel.AlignmentView; | |
27 | import jalview.datamodel.BinaryNode; | |
28 | import jalview.datamodel.CigarArray; | |
29 | import jalview.datamodel.SeqCigar; | |
30 | import jalview.datamodel.SequenceI; | |
31 | import jalview.datamodel.SequenceNode; | |
32 | import jalview.viewmodel.AlignmentViewport; | |
33 | ||
34 | ||
35 | import java.util.ArrayList; | |
36 | import java.util.BitSet; | |
37 | import java.util.List; | |
38 | import java.util.Vector; | |
39 | ||
40 | public abstract class TreeBuilder extends TreeEngine | |
41 | { | |
42 | public static final String AVERAGE_DISTANCE = "AV"; | |
43 | ||
44 | public static final String NEIGHBOUR_JOINING = "NJ"; | |
45 | ||
46 | protected SequenceI[] sequences; | |
47 | ||
48 | protected List<String> labels; | |
49 | ||
50 | public AlignmentView seqData; | |
51 | ||
52 | private AlignmentView seqStrings; | |
53 | ||
54 | /** | |
55 | * Constructor | |
56 | * | |
57 | * @param av | |
58 | * @param sm | |
59 | * @param scoreParameters | |
60 | */ | |
61 | 0 | public TreeBuilder(AlignmentViewport av, ScoreModelI sm, |
62 | SimilarityParamsI scoreParameters) | |
63 | { | |
64 | 0 | int start, end; |
65 | 0 | boolean selview = av.getSelectionGroup() != null |
66 | && av.getSelectionGroup().getSize() > 1; | |
67 | 0 | seqStrings = av.getAlignmentView(selview); |
68 | 0 | if (!selview) |
69 | { | |
70 | 0 | start = 0; |
71 | 0 | end = av.getAlignment().getWidth(); |
72 | 0 | this.sequences = av.getAlignment().getSequencesArray(); |
73 | } | |
74 | else | |
75 | { | |
76 | 0 | start = av.getSelectionGroup().getStartRes(); |
77 | 0 | end = av.getSelectionGroup().getEndRes() + 1; |
78 | 0 | this.sequences = av.getSelectionGroup() |
79 | .getSequencesInOrder(av.getAlignment()); | |
80 | } | |
81 | ||
82 | 0 | init(seqStrings, start, end); |
83 | ||
84 | 0 | computeTree(sm, scoreParameters); |
85 | } | |
86 | ||
87 | 0 | public SequenceI[] getSequences() |
88 | { | |
89 | 0 | return sequences; |
90 | } | |
91 | ||
92 | /** | |
93 | * | |
94 | * @return true if tree has real distances | |
95 | */ | |
96 | 0 | public boolean hasDistances() |
97 | { | |
98 | 0 | return true; |
99 | } | |
100 | ||
101 | /** | |
102 | * | |
103 | * @return true if tree has real bootstrap values | |
104 | */ | |
105 | 0 | public boolean hasBootstrap() |
106 | { | |
107 | 0 | return false; |
108 | } | |
109 | ||
110 | 0 | public boolean hasRootDistance() |
111 | { | |
112 | 0 | return true; |
113 | } | |
114 | ||
115 | 0 | public List<String> getLabels(){ |
116 | 0 | return this.labels; |
117 | } | |
118 | ||
119 | ArrayList<AlignmentAnnotation> ssAnnotationForSeqs; | |
120 | ||
121 | /** | |
122 | * Calculates the tree using the given score model and parameters, and the | |
123 | * configured tree type | |
124 | * <p> | |
125 | * If the score model computes pairwise distance scores, then these are used | |
126 | * directly to derive the tree | |
127 | * <p> | |
128 | * If the score model computes similarity scores, then the range of the scores | |
129 | * is reversed to give a distance measure, and this is used to derive the tree | |
130 | * | |
131 | * @param sm | |
132 | * @param scoreOptions | |
133 | */ | |
134 | 0 | protected void computeTree(ScoreModelI sm, SimilarityParamsI scoreOptions) |
135 | { | |
136 | 0 | labels = new ArrayList<String>(); |
137 | 0 | ssAnnotationForSeqs = new ArrayList<AlignmentAnnotation>(); |
138 | 0 | sequences = sm.expandSeqData(sequences, seqData, scoreOptions, |
139 | labels, ssAnnotationForSeqs); | |
140 | 0 | noseqs = sequences.length; |
141 | ||
142 | 0 | distances = sm.findDistances(seqData, scoreOptions); |
143 | ||
144 | 0 | makeLeaves(); |
145 | ||
146 | 0 | noClus = clusters.size(); |
147 | ||
148 | 0 | cluster(); |
149 | } | |
150 | ||
151 | 0 | protected void init(AlignmentView seqView, int start, int end) |
152 | { | |
153 | 0 | this.node = new Vector<BinaryNode>(); |
154 | 0 | if (seqView != null) |
155 | { | |
156 | 0 | this.seqData = seqView; |
157 | } | |
158 | else | |
159 | { | |
160 | 0 | SeqCigar[] seqs = new SeqCigar[sequences.length]; |
161 | 0 | for (int i = 0; i < sequences.length; i++) |
162 | { | |
163 | 0 | seqs[i] = new SeqCigar(sequences[i], start, end); |
164 | } | |
165 | 0 | CigarArray sdata = new CigarArray(seqs); |
166 | 0 | sdata.addOperation(CigarArray.M, end - start + 1); |
167 | 0 | this.seqData = new AlignmentView(sdata, start); |
168 | } | |
169 | ||
170 | /* | |
171 | * count the non-null sequences | |
172 | */ | |
173 | 0 | noseqs = 0; |
174 | ||
175 | 0 | done = new BitSet(); |
176 | ||
177 | 0 | for (SequenceI seq : sequences) |
178 | { | |
179 | 0 | if (seq != null) |
180 | { | |
181 | 0 | noseqs++; |
182 | } | |
183 | } | |
184 | } | |
185 | ||
186 | /** | |
187 | * Start by making a cluster for each individual sequence | |
188 | */ | |
189 | 0 | void makeLeaves() |
190 | { | |
191 | 0 | clusters = new Vector<BitSet>(); |
192 | ||
193 | 0 | for (int i = 0; i < noseqs; i++) |
194 | { | |
195 | 0 | SequenceNode sn = new SequenceNode(); |
196 | ||
197 | 0 | sn.setElement(sequences[i]); |
198 | ||
199 | 0 | if (labels.size() == noseqs) |
200 | { | |
201 | 0 | sn.setLabel(labels.get(i)); |
202 | } | |
203 | ||
204 | 0 | if (ssAnnotationForSeqs != null && !ssAnnotationForSeqs.isEmpty()) |
205 | { | |
206 | 0 | sn.setAlignmentAnnotation(ssAnnotationForSeqs.get(i)); |
207 | } | |
208 | ||
209 | 0 | sn.setName(sequences[i].getName()); |
210 | ||
211 | 0 | node.addElement(sn); |
212 | 0 | BitSet bs = new BitSet(); |
213 | 0 | bs.set(i); |
214 | 0 | clusters.addElement(bs); |
215 | } | |
216 | } | |
217 | ||
218 | 0 | public AlignmentView getOriginalData() |
219 | { | |
220 | 0 | return seqStrings; |
221 | } | |
222 | ||
223 | } |