Class |
Line # |
Actions |
|||
---|---|---|---|---|---|
PCAModel | 35 | 61 | 29 |
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.viewmodel; | |
22 | ||
23 | import jalview.analysis.PCA; | |
24 | import jalview.api.RotatableCanvasI; | |
25 | import jalview.api.analysis.ScoreModelI; | |
26 | import jalview.api.analysis.SimilarityParamsI; | |
27 | import jalview.datamodel.AlignmentView; | |
28 | import jalview.datamodel.Point; | |
29 | import jalview.datamodel.SequenceI; | |
30 | import jalview.datamodel.SequencePoint; | |
31 | ||
32 | import java.util.List; | |
33 | import java.util.Vector; | |
34 | ||
35 | public class PCAModel | |
36 | { | |
37 | /* | |
38 | * inputs | |
39 | */ | |
40 | private AlignmentView inputData; | |
41 | ||
42 | private final SequenceI[] seqs; | |
43 | ||
44 | private final SimilarityParamsI similarityParams; | |
45 | ||
46 | /* | |
47 | * options - score model, nucleotide / protein | |
48 | */ | |
49 | private ScoreModelI scoreModel; | |
50 | ||
51 | private boolean nucleotide = false; | |
52 | ||
53 | /* | |
54 | * outputs | |
55 | */ | |
56 | private PCA pca; | |
57 | ||
58 | int top; | |
59 | ||
60 | private List<SequencePoint> points; | |
61 | ||
62 | /** | |
63 | * Constructor given sequence data, score model and score calculation | |
64 | * parameter options. | |
65 | * | |
66 | * @param seqData | |
67 | * @param sqs | |
68 | * @param nuc | |
69 | * @param modelName | |
70 | * @param params | |
71 | */ | |
72 | 2 | public PCAModel(AlignmentView seqData, SequenceI[] sqs, boolean nuc, |
73 | ScoreModelI modelName, SimilarityParamsI params) | |
74 | { | |
75 | 2 | inputData = seqData; |
76 | 2 | seqs = sqs; |
77 | 2 | nucleotide = nuc; |
78 | 2 | scoreModel = modelName; |
79 | 2 | similarityParams = params; |
80 | } | |
81 | ||
82 | /** | |
83 | * Performs the PCA calculation (in the same thread) and extracts result data | |
84 | * needed for visualisation by PCAPanel | |
85 | */ | |
86 | 1 | public void calculate() |
87 | { | |
88 | 1 | pca = new PCA(inputData, scoreModel, similarityParams); |
89 | 1 | pca.run(); // executes in same thread, wait for completion |
90 | ||
91 | // Now find the component coordinates | |
92 | 1 | int ii = 0; |
93 | ||
94 | 16 | while ((ii < seqs.length) && (seqs[ii] != null)) |
95 | { | |
96 | 15 | ii++; |
97 | } | |
98 | ||
99 | 1 | int height = pca.getHeight(); |
100 | // top = pca.getM().height() - 1; | |
101 | 1 | top = height - 1; |
102 | ||
103 | 1 | points = new Vector<>(); |
104 | 1 | Point[] scores = pca.getComponents(top - 1, top - 2, top - 3, 1); |
105 | ||
106 | 16 | for (int i = 0; i < height; i++) |
107 | { | |
108 | 15 | SequencePoint sp = new SequencePoint(seqs[i], scores[i]); |
109 | 15 | points.add(sp); |
110 | } | |
111 | } | |
112 | ||
113 | 1 | public void updateRc(RotatableCanvasI rc) |
114 | { | |
115 | 1 | rc.setPoints(points, pca.getHeight()); |
116 | } | |
117 | ||
118 | 0 | public boolean isNucleotide() |
119 | { | |
120 | 0 | return nucleotide; |
121 | } | |
122 | ||
123 | 0 | public void setNucleotide(boolean nucleotide) |
124 | { | |
125 | 0 | this.nucleotide = nucleotide; |
126 | } | |
127 | ||
128 | /** | |
129 | * Answers the index of the principal dimension of the PCA | |
130 | * | |
131 | * @return | |
132 | */ | |
133 | 1 | public int getTop() |
134 | { | |
135 | 1 | return top; |
136 | } | |
137 | ||
138 | 1 | public void setTop(int t) |
139 | { | |
140 | 1 | top = t; |
141 | } | |
142 | ||
143 | /** | |
144 | * Updates the 3D coordinates for the list of points to the given dimensions. | |
145 | * Principal dimension is getTop(). Next greatest eigenvector is getTop()-1. | |
146 | * Note - pca.getComponents starts counting the spectrum from rank-2 to zero, | |
147 | * rather than rank-1, so getComponents(dimN ...) == updateRcView(dimN+1 ..) | |
148 | * | |
149 | * @param dim1 | |
150 | * @param dim2 | |
151 | * @param dim3 | |
152 | */ | |
153 | 0 | public void updateRcView(int dim1, int dim2, int dim3) |
154 | { | |
155 | // note: actual indices for components are dim1-1, etc (patch for JAL-1123) | |
156 | 0 | Point[] scores = pca.getComponents(dim1 - 1, dim2 - 1, dim3 - 1, 1); |
157 | ||
158 | 0 | for (int i = 0; i < pca.getHeight(); i++) |
159 | { | |
160 | 0 | points.get(i).coord = scores[i]; |
161 | } | |
162 | } | |
163 | ||
164 | 0 | public String getDetails() |
165 | { | |
166 | 0 | return pca.getDetails(); |
167 | } | |
168 | ||
169 | 0 | public AlignmentView getInputData() |
170 | { | |
171 | 0 | return inputData; |
172 | } | |
173 | ||
174 | 1 | public void setInputData(AlignmentView data) |
175 | { | |
176 | 1 | inputData = data; |
177 | } | |
178 | ||
179 | 0 | public String getPointsasCsv(boolean transformed, int xdim, int ydim, |
180 | int zdim) | |
181 | { | |
182 | 0 | StringBuffer csv = new StringBuffer(); |
183 | 0 | csv.append("\"Sequence\""); |
184 | 0 | if (transformed) |
185 | { | |
186 | 0 | csv.append(","); |
187 | 0 | csv.append(xdim); |
188 | 0 | csv.append(","); |
189 | 0 | csv.append(ydim); |
190 | 0 | csv.append(","); |
191 | 0 | csv.append(zdim); |
192 | } | |
193 | else | |
194 | { | |
195 | 0 | for (int d = 1, dmax = pca.component(1).length; d <= dmax; d++) |
196 | { | |
197 | 0 | csv.append("," + d); |
198 | } | |
199 | } | |
200 | 0 | csv.append("\n"); |
201 | 0 | for (int s = 0; s < seqs.length; s++) |
202 | { | |
203 | 0 | csv.append("\"" + seqs[s].getName() + "\""); |
204 | 0 | double fl[]; |
205 | 0 | if (!transformed) |
206 | { | |
207 | // output pca in correct order | |
208 | 0 | fl = pca.component(s); |
209 | 0 | for (int d = fl.length - 1; d >= 0; d--) |
210 | { | |
211 | 0 | csv.append(","); |
212 | 0 | csv.append(fl[d]); |
213 | } | |
214 | } | |
215 | else | |
216 | { | |
217 | 0 | Point p = points.get(s).coord; |
218 | 0 | csv.append(",").append(p.x); |
219 | 0 | csv.append(",").append(p.y); |
220 | 0 | csv.append(",").append(p.z); |
221 | } | |
222 | 0 | csv.append("\n"); |
223 | } | |
224 | 0 | return csv.toString(); |
225 | } | |
226 | ||
227 | 3 | public String getScoreModelName() |
228 | { | |
229 | 3 | return scoreModel == null ? "" : scoreModel.getName(); |
230 | } | |
231 | ||
232 | 0 | public void setScoreModel(ScoreModelI sm) |
233 | { | |
234 | 0 | this.scoreModel = sm; |
235 | } | |
236 | ||
237 | /** | |
238 | * Answers the parameters configured for pairwise similarity calculations | |
239 | * | |
240 | * @return | |
241 | */ | |
242 | 1 | public SimilarityParamsI getSimilarityParameters() |
243 | { | |
244 | 1 | return similarityParams; |
245 | } | |
246 | ||
247 | 1 | public List<SequencePoint> getSequencePoints() |
248 | { | |
249 | 1 | return points; |
250 | } | |
251 | ||
252 | 1 | public void setSequencePoints(List<SequencePoint> sp) |
253 | { | |
254 | 1 | points = sp; |
255 | } | |
256 | ||
257 | /** | |
258 | * Answers the object holding the values of the computed PCA | |
259 | * | |
260 | * @return | |
261 | */ | |
262 | 1 | public PCA getPcaData() |
263 | { | |
264 | 1 | return pca; |
265 | } | |
266 | ||
267 | 1 | public void setPCA(PCA data) |
268 | { | |
269 | 1 | pca = data; |
270 | } | |
271 | } |