Clover icon

Coverage Report

  1. Project Clover database Wed Feb 4 2026 17:46:51 GMT
  2. Package jalview.viewmodel

File PCAModel.java

 

Coverage histogram

../../img/srcFileCovDistChart4.png
49% of files have more coverage

Code metrics

28
74
20
1
315
196
38
0.51
3.7
20
1.9

Classes

Class Line # Actions
PCAModel 40 74 38
0.3934426339.3%
 

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