Clover icon

Coverage Report

  1. Project Clover database Mon Nov 11 2024 15:05:32 GMT
  2. Package jalview.analysis

File PCA.java

 

Coverage histogram

../../img/srcFileCovDistChart5.png
43% of files have more coverage

Code metrics

16
85
26
1
377
214
35
0.41
3.27
26
1.35

Classes

Class Line # Actions
PCA 37 85 35
0.49606349.6%
 

Contributing tests

This file is covered by 1 test. .

Source view

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.bin.Console;
26    import jalview.datamodel.AlignmentView;
27    import jalview.datamodel.Point;
28    import jalview.math.MatrixI;
29   
30    import java.io.PrintStream;
31    import java.util.HashMap;
32    import java.util.Map;
33   
34    /**
35    * Performs Principal Component Analysis on given sequences
36    */
 
37    public class PCA implements Runnable, SpatialCalculationI
38    {
39    /*
40    * inputs
41    */
42    final private AlignmentView seqs;
43   
44    final private ScoreModelI scoreModel;
45   
46    final private SimilarityParamsI similarityParams;
47   
48    /*
49    * outputs
50    */
51    private MatrixI pairwiseScores;
52   
53    private MatrixI tridiagonal;
54   
55    private MatrixI eigenMatrix;
56   
57    /**
58    * Constructor given the sequences to compute for, the similarity model to
59    * use, and a set of parameters for sequence comparison
60    *
61    * @param sequences
62    * @param sm
63    * @param options
64    */
 
65  2 toggle public PCA(AlignmentView sequences, ScoreModelI sm,
66    SimilarityParamsI options)
67    {
68  2 this.seqs = sequences;
69  2 this.scoreModel = sm;
70  2 this.similarityParams = options;
71    }
72   
73    /**
74    * Returns Eigenvalue
75    *
76    * @param i
77    * Index of diagonal within matrix
78    *
79    * @return Returns value of diagonal from matrix
80    */
 
81  0 toggle public double getEigenvalue(int i)
82    {
83  0 return eigenMatrix.getD()[i];
84    }
85   
86    /**
87    * DOCUMENT ME!
88    *
89    * @param l
90    * DOCUMENT ME!
91    * @param n
92    * DOCUMENT ME!
93    * @param mm
94    * DOCUMENT ME!
95    * @param factor
96    * DOCUMENT ME!
97    *
98    * @return DOCUMENT ME!
99    */
 
100  1 toggle public Point[] getComponents(int l, int n, int mm, float factor)
101    {
102  1 Point[] out = new Point[getHeight()];
103   
104  16 for (int i = 0; i < getHeight(); i++)
105    {
106  15 float x = (float) component(i, l) * factor;
107  15 float y = (float) component(i, n) * factor;
108  15 float z = (float) component(i, mm) * factor;
109  15 out[i] = new Point(x, y, z);
110    }
111   
112  1 return out;
113    }
114   
115    /**
116    * DOCUMENT ME!
117    *
118    * @param n
119    * DOCUMENT ME!
120    *
121    * @return DOCUMENT ME!
122    */
 
123  0 toggle public double[] component(int n)
124    {
125    // n = index of eigenvector
126  0 double[] out = new double[getHeight()];
127   
128  0 for (int i = 0; i < out.length; i++)
129    {
130  0 out[i] = component(i, n);
131    }
132   
133  0 return out;
134    }
135   
136    /**
137    * DOCUMENT ME!
138    *
139    * @param row
140    * DOCUMENT ME!
141    * @param n
142    * DOCUMENT ME!
143    *
144    * @return DOCUMENT ME!
145    */
 
146  45 toggle double component(int row, int n)
147    {
148  45 double out = 0.0;
149   
150  720 for (int i = 0; i < pairwiseScores.width(); i++)
151    {
152  675 out += (pairwiseScores.getValue(row, i) * eigenMatrix.getValue(i, n));
153    }
154   
155  45 return out / eigenMatrix.getD()[n];
156    }
157   
158    /**
159    * Answers a formatted text report of the PCA calculation results (matrices
160    * and eigenvalues) suitable for display
161    *
162    * @return
163    */
 
164  0 toggle public String getDetails()
165    {
166  0 StringBuilder sb = new StringBuilder(1024);
167  0 sb.append("PCA calculation using ").append(scoreModel.getName())
168    .append(" sequence similarity matrix\n========\n\n");
169  0 PrintStream ps = wrapOutputBuffer(sb);
170   
171    /*
172    * pairwise similarity scores
173    */
174  0 sb.append(" --- OrigT * Orig ---- \n");
175  0 pairwiseScores.print(ps, "%8.2f");
176   
177    /*
178    * tridiagonal matrix, with D and E vectors
179    */
180  0 sb.append(" ---Tridiag transform matrix ---\n");
181  0 sb.append(" --- D vector ---\n");
182  0 tridiagonal.printD(ps, "%15.4e");
183  0 ps.println();
184  0 sb.append("--- E vector ---\n");
185  0 tridiagonal.printE(ps, "%15.4e");
186  0 ps.println();
187   
188    /*
189    * eigenvalues matrix, with D vector
190    */
191  0 sb.append(" --- New diagonalization matrix ---\n");
192  0 eigenMatrix.print(ps, "%8.2f");
193  0 sb.append(" --- Eigenvalues ---\n");
194  0 eigenMatrix.printD(ps, "%15.4e");
195  0 ps.println();
196   
197  0 return sb.toString();
198    }
199   
200    /**
201    * Performs the PCA calculation
202    */
 
203  1 toggle @Override
204    public void run()
205    {
206  1 isCancelled=false;
207  1 try
208    {
209    /*
210    * sequence pairwise similarity scores
211    */
212  1 pairwiseScores = scoreModel.findSimilarities(seqs, similarityParams);
213  1 if (isCancelled())
214    {
215  0 pairwiseScores=null;
216  0 return;
217    }
218    /*
219    * tridiagonal matrix
220    */
221   
222  1 tridiagonal = pairwiseScores.copy();
223  1 if (isCancelled()) {
224  0 clearResults();
225  0 return;
226    }
227  1 tridiagonal.tred();
228  1 if (isCancelled()) {
229  0 clearResults();
230  0 return;
231    }
232    /*
233    * the diagonalization matrix
234    */
235  1 eigenMatrix = tridiagonal.copy();
236  1 if (isCancelled()) {
237  0 clearResults();
238  0 return;
239    }
240  1 eigenMatrix.tqli();
241  1 if (isCancelled()) {
242  0 clearResults();
243  0 return;
244    }
245    } catch (Exception q)
246    {
247  0 Console.error("Error computing PCA: " + q.getMessage());
248  0 q.printStackTrace();
249    }
250    }
 
251  0 toggle private void clearResults()
252    {
253  0 pairwiseScores = null;
254  0 tridiagonal = null;
255  0 eigenMatrix = null;
256    }
257    /**
258    * Returns a PrintStream that wraps (appends its output to) the given
259    * StringBuilder
260    *
261    * @param sb
262    * @return
263    */
 
264  0 toggle protected PrintStream wrapOutputBuffer(StringBuilder sb)
265    {
266  0 PrintStream ps = new PrintStream(System.out)
267    {
 
268  0 toggle @Override
269    public void print(String x)
270    {
271  0 sb.append(x);
272    }
273   
 
274  0 toggle @Override
275    public void println()
276    {
277  0 sb.append("\n");
278    }
279    };
280  0 return ps;
281    }
282   
283    /**
284    * Answers the N dimensions of the NxN PCA matrix. This is the number of
285    * sequences involved in the pairwise score calculation.
286    *
287    * @return
288    */
 
289  20 toggle public int getHeight()
290    {
291    // TODO can any of seqs[] be null?
292  20 return pairwiseScores.height();// seqs.getSequences().length;
293    }
 
294  1 toggle @Override
295    public int getWidth()
296    {
297  1 return getHeight();
298    }
 
299  0 toggle @Override
300    public int getDim()
301    {
302  0 return component(1).length;
303    }
 
304  1 toggle public int getTop()
305    {
306  1 return pairwiseScores.height()-1;
307    }
308    /**
309    * Answers the sequence pairwise similarity scores which were the first step
310    * of the PCA calculation
311    *
312    * @return
313    */
 
314  1 toggle public MatrixI getPairwiseScores()
315    {
316  1 return pairwiseScores;
317    }
318   
 
319  1 toggle public void setPairwiseScores(MatrixI m)
320    {
321  1 pairwiseScores = m;
322    }
323   
 
324  1 toggle public MatrixI getEigenmatrix()
325    {
326  1 return eigenMatrix;
327    }
328   
 
329  1 toggle public void setEigenmatrix(MatrixI m)
330    {
331  1 eigenMatrix = m;
332    }
333   
 
334  1 toggle public MatrixI getTridiagonal()
335    {
336  1 return tridiagonal;
337    }
338   
 
339  1 toggle public void setTridiagonal(MatrixI tridiagonal)
340    {
341  1 this.tridiagonal = tridiagonal;
342    }
343   
344    volatile boolean isCancelled = false;
 
345  0 toggle @Override
346    public void cancel()
347    {
348  0 isCancelled = true;
349    }
 
350  0 toggle @Override
351    public boolean isCancellable()
352    {
353  0 return true;
354    }
 
355  6 toggle @Override
356    public boolean isCancelled()
357    {
358  6 return isCancelled;
359    }
 
360  0 toggle @Override
361    public String getAlignmentOutput()
362    {
363    // TODO Auto-generated method stub
364  0 return null;
365    }
366   
367    public static final String PAIRWISE_SIMILARITY="PCA Input Similarity";
 
368  1 toggle @Override
369    public Map<String,MatrixI> getDistanceMatrices()
370    {
371  1 Map<String, MatrixI> clusterables = new HashMap<String, MatrixI>();
372  1 clusterables.put(PAIRWISE_SIMILARITY,pairwiseScores);
373    // clusterables.put(PASIMAP_ANGLE, eigenMatrix);
374  1 return clusterables;
375    }
376   
377    }