Clover icon

Coverage Report

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

File PaSiMap.java

 

Coverage histogram

../../img/srcFileCovDistChart0.png
60% of files have more coverage

Code metrics

16
83
25
1
420
221
35
0.42
3.32
25
1.4

Classes

Class Line # Actions
PaSiMap 46 83 35
0.00%
 

Contributing tests

No tests hitting this source file were found.

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.analysis.scoremodels.ScoreMatrix;
26    import jalview.analysis.scoremodels.ScoreModels;
27    import jalview.bin.Console;
28    import jalview.datamodel.Point;
29    import jalview.datamodel.SequenceI;
30    import jalview.datamodel.SequenceGroup;
31    import jalview.gui.PairwiseAlignPanel;
32    import jalview.math.Matrix;
33    import jalview.math.MatrixI;
34    import jalview.viewmodel.AlignmentViewport;
35   
36    import java.io.PrintStream;
37    import java.util.HashMap;
38    import java.util.Hashtable;
39    import java.util.Map;
40   
41    /**
42    * Performs Principal Component Analysis on given sequences
43    *
44    * @AUTHOR MorellThomas
45    */
 
46    public class PaSiMap implements Runnable,SpatialCalculationI
47    {
48    /*
49    * inputs
50    */
51    final private AlignmentViewport seqs;
52   
53    final private ScoreMatrix scoreMatrix;
54   
55    final private byte dim = 8;
56   
57    final private int openCost = 100;
58   
59    final private int extendCost = 5;
60   
61    /*
62    * outputs
63    */
64    final private PairwiseAlignPanel alignment;
65   
66    private boolean cancelled=false;
67   
68    private MatrixI pairwiseScores;
69   
70    private MatrixI eigenMatrix;
71   
72    private volatile boolean canCancel;
73   
74    /**
75    * Constructor given the sequences to compute for, the similarity model to
76    * use, and a set of parameters for sequence comparison
77    *
78    * @param sequences
79    * @param sm
80    * @param options
81    */
 
82  0 toggle public PaSiMap(AlignmentViewport sequences, ScoreModelI sm,
83    PairwiseAlignPanel pap)
84    {
85  0 this.seqs = sequences;
86   
87  0 if (sm != null && sm instanceof ScoreMatrix)
88    {
89  0 this.scoreMatrix = ((ScoreMatrix) sm);
90    }
91    else
92    {
93  0 this.scoreMatrix = null;
94    }
95   
96  0 this.alignment = pap;
97    }
98   
99    /**
100    * Returns Eigenvalue
101    *
102    * @param i
103    * Index of diagonal within matrix
104    *
105    * @return Returns value of diagonal from matrix
106    */
 
107  0 toggle public double getEigenvalue(int i)
108    {
109  0 return eigenMatrix.getD()[i];
110    }
111   
112    /**
113    * Returns coordinates for each datapoint
114    *
115    * @param l
116    * DOCUMENT ME!
117    * @param n
118    * DOCUMENT ME!
119    * @param mm
120    * DOCUMENT ME!
121    * @param factor
122    * ~ is 1
123    *
124    * @return DOCUMENT ME!
125    */
 
126  0 toggle public Point[] getComponents(int l, int n, int mm, float factor)
127    {
128  0 Point[] out = new Point[getHeight()];
129   
130  0 for (int i = 0; i < out.length; i++)
131    {
132  0 float x = (float) component(i, l) * factor;
133  0 float y = (float) component(i, n) * factor;
134  0 float z = (float) component(i, mm) * factor;
135  0 out[i] = new Point(x, y, z);
136    }
137   
138  0 return out;
139    }
140   
141    /**
142    * DOCUMENT ME!
143    *
144    * @param n
145    * DOCUMENT ME!
146    *
147    * @return DOCUMENT ME!
148    */
 
149  0 toggle public double[] component(int n)
150    {
151    // n = index of eigenvector
152  0 double[] out = new double[getWidth()];
153   
154  0 for (int i = 0; i < out.length; i++)
155    {
156  0 out[i] = component(n, i);
157    }
158   
159  0 return out;
160    }
161   
162    /**
163    * DOCUMENT ME!
164    *
165    * @param row
166    * DOCUMENT ME!
167    * @param n
168    * DOCUMENT ME!
169    *
170    * @return DOCUMENT ME!
171    */
 
172  0 toggle double component(int row, int n)
173    {
174  0 return eigenMatrix.getValue(row, n);
175    }
176   
177    /**
178    * Answers a formatted text report of the PaSiMap calculation results
179    * (matrices and eigenvalues) suitable for display
180    *
181    * @return
182    */
 
183  0 toggle public String getDetails()
184    {
185  0 StringBuilder sb = new StringBuilder(1024);
186  0 sb.append("PaSiMap calculation using ").append(scoreMatrix.getName())
187    .append(" sequence similarity matrix\n========\n\n");
188  0 PrintStream ps = wrapOutputBuffer(sb);
189   
190    /*
191    * coordinates matrix, with D vector
192    */
193  0 sb.append(" --- Pairwise correlation coefficients ---\n");
194  0 pairwiseScores.print(ps, "%8.6f ");
195  0 ps.println();
196   
197  0 sb.append(" --- Eigenvalues ---\n");
198  0 eigenMatrix.printD(ps, "%15.4e");
199  0 ps.println();
200   
201  0 sb.append(" --- Coordinates ---\n");
202  0 eigenMatrix.print(ps, "%8.6f ");
203  0 ps.println();
204   
205  0 return sb.toString();
206    }
207   
208    /**
209    * Performs the PaSiMap calculation
210    *
211    * creates a new gui/PairwiseAlignPanel with the input sequences
212    * (AlignmentViewport)
213    *
214    * uses analysis/AlignSeq to creatue the pairwise alignments and calculate the
215    * AlignmentScores (float for each pair)
216    *
217    * gets all float[][] scores from the gui/PairwiseAlignPanel
218    *
219    * checks the connections for each sequence with AlignmentViewport
220    * seqs.calculateConnectivity(float[][] scores, int dim) (from
221    * analysis/Connectivity) -- throws an Exception if insufficient
222    *
223    * creates a math/MatrixI pairwiseScores of the float[][] scores
224    *
225    * copys the scores and fills the diagonal to create a symmetric matrix using
226    * math/Matrix.fillDiagonal()
227    *
228    * performs the analysis/ccAnalysis with the symmetric matrix
229    *
230    * gets the eigenmatrix and the eigenvalues using math/Matrix.tqli()
231    */
 
232  0 toggle @Override
233    public void run()
234    {
235  0 canCancel=true;
236  0 try
237    {
238    // alignment = new PairwiseAlignPanel(seqs, true, 100, 5);
239  0 alignment.calculate(scoreMatrix);
240  0 if (alignment.isCancelled())
241    {
242  0 cancel();
243  0 return;
244    }
245    //alignment.setProgressMessage("Preparing to calculate pasimap...");
246  0 float[][] scores = alignment.getAlignmentScores(); // bigger index first
247    // -- eg scores[14][13]
248  0 SequenceI[] iseqs = alignment.getInputSequences();
249  0 Connectivity.getConnectivity(iseqs, scores, dim);
250   
251  0 canCancel=false;
252  0 alignment.updateProgress(PairwiseAlignPanel.PROGRESSMESSAGE, "Creating the PaSiMap");
253  0 pairwiseScores = new Matrix(scores);
254  0 pairwiseScores.fillDiagonal();
255   
256  0 eigenMatrix = pairwiseScores.copy();
257   
258  0 ccAnalysis cc = new ccAnalysis(pairwiseScores, dim);
259  0 eigenMatrix = cc.run().mirrorCol();
260  0 alignment.updateProgress(PairwiseAlignPanel.PROGRESSCOMPLETE, "Finished PaSiMap.");
261   
262    // create cluster matrices
263  0 clusterables = new HashMap<String, MatrixI>();
264  0 clusterables.put(PAIRWISE_SIMILARITY,pairwiseScores);
265  0 clusterables.put(PASIMAP_ANGLE, getArctan());
266   
267    } catch (Exception q)
268    {
269  0 Console.error("Error computing PaSiMap: " + q.getMessage());
270  0 q.printStackTrace();
271    }
272    }
273    Map<String, MatrixI> clusterables = new HashMap<String, MatrixI>();
274   
275    public static final String PAIRWISE_SIMILARITY="Smith Waterman Distance",PASIMAP_ANGLE="PaSiMap Projection";
 
276  0 toggle @Override
277    public Map<String,MatrixI> getDistanceMatrices()
278    {
279  0 return clusterables;
280    }
 
281  0 toggle public MatrixI getArctan()
282    {
283  0 MatrixI arcTan = pairwiseScores.copy();
284  0 float[] angles = new float[arcTan.width()];
285  0 for (int i=0;i<angles.length;i++)
286    {
287  0 angles[i] = (float) Math.atan2(component(i, getTop()-1),component(i, getTop()-2));
288    }
289  0 for (int i=0;i<arcTan.width()-1;i++)
290    {
291  0 for (int j=i;j<arcTan.width()-1;j++)
292    {
293  0 float val = Math.abs(angles[j]-angles[i]);
294  0 arcTan.setValue(i, j, val);
295  0 arcTan.setValue(j, i, val);
296    }
297    }
298  0 return arcTan;
299    }
300   
301   
 
302  0 toggle public void cancel()
303    {
304  0 if (alignment!=null)
305    {
306  0 alignment.cancel();
307    }
308  0 cancelled=true;
309    }
310   
 
311  0 toggle public boolean isCancelled()
312    {
313  0 return cancelled;
314    }
315   
316    /**
317    * Returns a PrintStream that wraps (appends its output to) the given
318    * StringBuilder
319    *
320    * @param sb
321    * @return
322    */
 
323  0 toggle protected PrintStream wrapOutputBuffer(StringBuilder sb)
324    {
325  0 PrintStream ps = new PrintStream(System.out)
326    {
 
327  0 toggle @Override
328    public void print(String x)
329    {
330  0 sb.append(x);
331    }
332   
 
333  0 toggle @Override
334    public void println()
335    {
336  0 sb.append("\n");
337    }
338    };
339  0 return ps;
340    }
341   
342    /**
343    * Answers the N dimensions of the NxM PaSiMap matrix. This is the number of
344    * sequences involved in the pairwise score calculation.
345    *
346    * @return
347    */
 
348  0 toggle public int getHeight()
349    {
350    // TODO can any of seqs[] be null?
351  0 return eigenMatrix.height();// seqs.getSequences().length;
352    }
353   
354    /**
355    * Answers the M dimensions of the NxM PaSiMap matrix. This is the number of
356    * sequences involved in the pairwise score calculation.
357    *
358    * @return
359    */
 
360  0 toggle public int getWidth()
361    {
362    // TODO can any of seqs[] be null?
363  0 return eigenMatrix.width();// seqs.getSequences().length;
364    }
365   
 
366  0 toggle public int getTop()
367    {
368  0 return getWidth()-1;
369    }
370   
371    /**
372    * Answers the sequence pairwise similarity scores which were the first step
373    * of the PaSiMap calculation
374    *
375    * @return
376    */
 
377  0 toggle public MatrixI getPairwiseScores()
378    {
379  0 return pairwiseScores;
380    }
381   
 
382  0 toggle public void setPairwiseScores(MatrixI m)
383    {
384  0 pairwiseScores = m;
385    }
386   
 
387  0 toggle public MatrixI getEigenmatrix()
388    {
389  0 return eigenMatrix;
390    }
391   
 
392  0 toggle public void setEigenmatrix(MatrixI m)
393    {
394  0 eigenMatrix = m;
395    }
396   
 
397  0 toggle public PairwiseAlignPanel getAlignments()
398    {
399  0 return alignment;
400    }
401   
 
402  0 toggle public String getAlignmentOutput()
403    {
404  0 return alignment.getAlignmentOutput();
405    }
406   
 
407  0 toggle public int getDim()
408    {
409  0 return dim;
410    }
411   
412    /**
413    *
414    * @return true if pasimap calculation can (still) be interrupted
415    */
 
416  0 toggle public boolean isCancellable()
417    {
418  0 return canCancel;
419    }
420    }