Clover icon

Coverage Report

  1. Project Clover database Wed Jan 7 2026 02:49:01 GMT
  2. Package jalview.gui

File PairwiseAlignPanel.java

 

Coverage histogram

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

Code metrics

48
128
24
1
488
313
51
0.4
5.33
24
2.12

Classes

Class Line # Actions
PairwiseAlignPanel 46 128 51
0.50550.5%
 

Contributing tests

This file is covered by 2 tests. .

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.gui;
22   
23    import jalview.analysis.AlignSeq;
24    import jalview.analysis.scoremodels.ScoreMatrix;
25    import jalview.api.analysis.ScoreModelI;
26    import jalview.api.analysis.SimilarityParamsI;
27    import jalview.api.AlignViewportI;
28    import jalview.datamodel.Alignment;
29    import jalview.datamodel.AlignmentView;
30    import jalview.datamodel.SequenceGroup;
31    import jalview.datamodel.SequenceI;
32    import jalview.jbgui.GPairwiseAlignPanel;
33    import jalview.util.MessageManager;
34    import jalview.viewmodel.AlignmentViewport;
35    import jalview.math.MiscMath;
36   
37    import java.awt.event.ActionEvent;
38    import java.util.Vector;
39   
40    /**
41    * DOCUMENT ME!
42    *
43    * @author $author$
44    * @version $Revision$
45    */
 
46    public class PairwiseAlignPanel extends GPairwiseAlignPanel
47    {
48   
49    private static final String DASHES = "---------------------\n";
50   
51    private float[][] scores;
52   
53    private float[][] alignmentScores; // scores used by PaSiMap
54   
55    private int GAP_OPEN_COST;
56   
57    private int GAP_EXTEND_COST;
58   
59    // TODO JAL-4107 can we make this AlignViewportI ?
60    AlignViewportI av;
61   
62    Vector<SequenceI> sequences;
63   
64    private String alignmentOutput;
65   
66    private boolean quiet;
67   
68    private boolean discardAlignments;
69   
70    private boolean endGaps;
71   
72    // for listening
73    public static final String TOTAL = "total";
74   
75    public static final String PROGRESS = "progress";
76   
77    protected static final String ETA = "eta_in_minutes";
78   
79    public static final String PROGRESSCOMPLETE = "finished_stop_progress";
80    public static final String PROGRESSMESSAGE = "message_in_progress";
81   
82    private volatile boolean cancelled;
83   
84    private long total;
85   
86    private long progress;
87   
88    private SequenceGroup selection;
89   
90    /**
91    * input sequences
92    */
93    private SequenceI[] seqs = null;
94   
95    private ScoreMatrix scoreMatrix;
96   
97    /**
98    * remaining time
99    */
100    private double etime=Double.NaN;
101   
102    /**
103    * Creates a new PairwiseAlignPanel object.
104    *
105    * @param viewport
106    * contains selected sequences to align
107    * @param endGaps
108    * ~ toggle gaps and the beginning and end of sequences
109    */
 
110  2 toggle public PairwiseAlignPanel(AlignViewportI viewport)
111    {
112  2 this(viewport, null, false, 120, 20, true, null); // default penalties used
113    // in AlignSeq
114    }
115   
 
116  0 toggle public PairwiseAlignPanel(AlignViewportI viewport, ScoreMatrix params)
117    {
118  0 this(viewport, null, false, 120, 20, true, params); // default penalties
119    // used in AlignSeq
120    }
121   
 
122  0 toggle public PairwiseAlignPanel(AlignViewportI viewport, boolean endGaps,
123    int gapOpenCost, int gapExtendCost)
124    {
125  0 this(viewport, null, endGaps, gapOpenCost, gapExtendCost, true, null);
126    }
127   
128    /**
129    * Create a new pairwise alignpanel with specified parameters and score model,
130    * and optionally start the calculation
131    *
132    * @param viewport
133    * @param selection
134    * @param endGaps
135    * @param gapOpenCost
136    * @param gapExtendCost
137    * @param run
138    * @param scoreMatrix
139    */
 
140  2 toggle public PairwiseAlignPanel(AlignViewportI viewport,
141    SequenceGroup selection, boolean endGaps, int gapOpenCost,
142    int gapExtendCost, boolean run, ScoreMatrix scoreMatrix)
143    {
144  2 super();
145  2 this.av = viewport;
146  2 this.GAP_OPEN_COST = gapOpenCost;
147  2 this.GAP_EXTEND_COST = gapExtendCost;
148  2 this.endGaps = endGaps;
149  2 this.selection = selection;
150  2 this.total = av.getAlignment().getHeight();
151  2 total = (total*total-total)/2;
152  2 this.scoreMatrix = scoreMatrix;
153  2 if (run)
154    {
155  2 calculate();
156    }
157    }
158   
 
159  2 toggle public void calculate()
160    {
161  2 calculate(scoreMatrix);
162    }
163   
 
164  2 toggle public void calculate(ScoreMatrix sm)
165    {
166  2 cancelled=false;
167  2 StringBuilder sb = new StringBuilder(1024);
168   
169  2 sequences = new Vector<SequenceI>();
170  2 String[] seqStrings;
171  2 seqs = null;
172   
173  2 if (selection != null)
174    {
175    // given a set of sequences to compare
176  0 seqs = selection.getSelectionAsNewSequences(av.getAlignment());
177  0 seqStrings = new String[seqs.length];
178  0 int s = 0;
179  0 for (SequenceI seq : seqs)
180    {
181  0 seqStrings[s++] = seq.getSequenceAsString();
182    }
183    }
184    else
185    {
186  2 SequenceGroup selectionGroup = av.getSelectionGroup();
187  2 boolean isSelection = selectionGroup != null
188    && selectionGroup.getSize() > 0;
189  2 AlignmentView view = av.getAlignmentView(isSelection);
190  2 seqStrings = view.getSequenceStrings(av.getGapCharacter());
191  2 if (isSelection)
192    {
193  1 seqs = (SequenceI[]) view
194    .getAlignmentAndHiddenColumns(av.getGapCharacter())[0];
195    }
196    else
197    {
198  1 seqs = av.getAlignment().getSequencesArray();
199    }
200    }
201   
202  2 String type = (av.getAlignment().isNucleotide()) ? AlignSeq.DNA
203    : AlignSeq.PEP;
204   
205  2 float[][] scores = new float[seqs.length][seqs.length];
206  2 float[][] alignmentScores = new float[seqs.length][seqs.length];
207  2 double totscore = 0D;
208  2 int count = seqs.length;
209  2 int fracprogress=0;
210  2 boolean first = true;
211  2 long time=System.currentTimeMillis();
212  2 long fprogress = 0;
213  2 firePropertyChange(TOTAL, 0, 500);
214   
215  4 for (int i = 1; i < count; i++)
216    {
217    // fill diagonal alignmentScores with Float.NaN
218  2 alignmentScores[i - 1][i - 1] = Float.NaN;
219  4 for (int j = 0; j < i; j++)
220    {
221  2 if (cancelled)
222    {
223  0 alignmentOutput = "Alignment was cancelled.";
224  0 return;
225    }
226  2 AlignSeq as = new AlignSeq(seqs[i], seqStrings[i], seqs[j],
227    seqStrings[j], type, GAP_OPEN_COST, GAP_EXTEND_COST);
228   
229  2 if (sm != null)
230    {
231  0 as.setScoreMatrix(sm);
232    }
233   
234  2 if (as.s1str.length() == 0 || as.s2str.length() == 0)
235    {
236  0 continue;
237    }
238  2 if (sm!=null)
239    {
240  0 as.setScoreMatrix(sm);
241    }
242  2 as.calcScoreMatrix();
243  2 if (endGaps)
244    {
245  0 as.traceAlignmentWithEndGaps();
246    }
247    else
248    {
249  2 as.traceAlignment();
250    }
251  2 as.scoreAlignment();
252   
253  2 if (!first && !quiet)
254    {
255  0 jalview.bin.Console.outPrintln(DASHES);
256  0 textarea.append(DASHES);
257  0 sb.append(DASHES);
258    }
259  2 first = false;
260  2 if (!discardAlignments)
261    {
262  2 as.printAlignment(System.out);
263    }
264  2 scores[i][j] = as.getMaxScore() / as.getASeq1().length;
265  2 alignmentScores[i][j] = as.getAlignmentScore();
266  2 totscore = totscore + scores[i][j];
267  2 if (!quiet)
268    {
269  2 textarea.append(as.getOutput());
270  2 sb.append(as.getOutput());
271    }
272  2 if (!discardAlignments)
273    {
274  2 sequences.add(as.getAlignedSeq1());
275  2 sequences.add(as.getAlignedSeq2());
276    }
277  2 ++fprogress;
278    }
279  2 if (i<count)
280    {
281  2 int newfracprogress=(int) Math.floor((500.0*(double)fprogress)/((double)total));
282    // need to fake a different starting value until we have an ETA calculated
283  2 firePropertyChange(PROGRESS, fracprogress, newfracprogress);
284  2 fracprogress = newfracprogress;
285  2 progress=fprogress;
286    // remaining time in minutes ~ is remaining*(elapsed time)/progress;
287  2 double lasteta=etime;
288  2 double rate = ((double)(System.currentTimeMillis()-time))/(double)progress;
289  2 etime = rate*(total-progress)/60000;
290  2 firePropertyChange(ETA, lasteta,etime);
291    }
292    }
293  2 alignmentScores[count - 1][count - 1] = Float.NaN;
294    // done - mark progress as indeterminate again
295  2 firePropertyChange(TOTAL, -1, -2);
296   
297   
298  2 this.scores = scores;
299  2 this.alignmentScores = alignmentScores;
300   
301  2 if (count > 2 && !quiet)
302    {
303  0 printScoreMatrix(seqs, scores, totscore);
304    }
305   
306  2 alignmentOutput = sb.toString();
307    }
308   
 
309  0 toggle public boolean hasEta()
310    {
311  0 return etime>0;
312    }
 
313  0 toggle public double getEta()
314    {
315  0 return etime;
316    }
317    /**
318    * stops the run() loop ASAP
319    */
 
320  0 toggle public void cancel()
321    {
322  0 cancelled=true;
323    }
324   
 
325  0 toggle public float[][] getScores()
326    {
327  0 return this.scores;
328    }
329   
 
330  0 toggle public float[][] getAlignmentScores()
331    {
332  0 return this.alignmentScores;
333    }
334   
 
335  0 toggle public String getAlignmentOutput()
336    {
337  0 return this.alignmentOutput;
338    }
339   
340    /**
341    * Prints a matrix of seqi-seqj pairwise alignment scores to sysout
342    *
343    * @param seqs
344    * @param scores
345    * @param totscore
346    */
 
347  0 toggle protected void printScoreMatrix(SequenceI[] seqs, float[][] scores,
348    double totscore)
349    {
350  0 System.out
351    .println("Pairwise alignment scaled similarity score matrix "+getPairwiseSimscoresAsString()+"\n");
352   
353  0 for (int i = 0; i < seqs.length; i++)
354    {
355  0 jalview.bin.Console.outPrintln(
356    String.format("%3d %s", i + 1, seqs[i].getDisplayId(true)));
357    }
358   
359    /*
360    * table heading columns for sequences 1, 2, 3...
361    */
362  0 System.out.print("\n ");
363  0 for (int i = 0; i < seqs.length; i++)
364    {
365  0 System.out.print(String.format("%7d", i + 1));
366    }
367  0 jalview.bin.Console.outPrintln();
368   
369  0 for (int i = 0; i < seqs.length; i++)
370    {
371  0 System.out.print(String.format("%3d", i + 1));
372  0 for (int j = 0; j < i; j++)
373    {
374    /*
375    * as a fraction of tot score, outputs are 0 <= score <= 1
376    */
377  0 System.out.print(String.format("%7.3f", scores[i][j] / totscore));
378    }
379  0 jalview.bin.Console.outPrintln();
380    }
381   
382  0 jalview.bin.Console.outPrintln("\n");
383    }
384   
 
385  0 toggle public String getPairwiseSimscoresAsString()
386    {
387  0 return (scoreMatrix != null
388    ? " (" + scoreMatrix.getName() + ", open=" + GAP_OPEN_COST
389    + ", extend=" + GAP_EXTEND_COST
390  0 + (endGaps ? ", with endGaps" : ", no endGaps") + ")"
391    : "");
392    }
393   
394    /**
395    * DOCUMENT ME!
396    *
397    * @param e
398    * DOCUMENT ME!
399    */
 
400  0 toggle @Override
401    protected void viewInEditorButton_actionPerformed(ActionEvent e)
402    {
403  0 SequenceI[] seq = new SequenceI[sequences.size()];
404   
405  0 for (int i = 0; i < sequences.size(); i++)
406    {
407  0 seq[i] = sequences.elementAt(i);
408    }
409   
410  0 AlignFrame af = new AlignFrame(new Alignment(seq),
411    AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
412   
413  0 Desktop.addInternalFrame(af,
414    MessageManager.getString("label.pairwise_aligned_sequences")+" "+getPairwiseSimscoresAsString(),
415    AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
416    }
417   
 
418  0 toggle public long getTotal()
419    {
420  0 return total;
421    }
422   
 
423  0 toggle public long getProgress()
424    {
425  0 return progress;
426    }
427   
 
428  0 toggle public SequenceI[] getInputSequences()
429    {
430  0 return seqs;
431    }
432   
433    /**
434    * Set to true to suppress output of progress to Console.stdout or GUI
435    *
436    * @param quiet
437    */
 
438  0 toggle public void setQuiet(boolean quiet)
439    {
440  0 this.quiet = quiet;
441    }
442   
443    /**
444    * @return true if no textual alignment report was generated
445    */
 
446  0 toggle public boolean isQuiet()
447    {
448  0 return quiet;
449    }
450   
451    /**
452    * set this if you are only interested in final alignment scores
453    *
454    * @param discard
455    */
 
456  0 toggle public void setDiscardAlignments(boolean discard)
457    {
458  0 discardAlignments = discard;
459    }
460   
461    /**
462    * @return true if no alignments were saved
463    * @return
464    */
 
465  0 toggle public boolean isDiscardAlignments()
466    {
467  0 return discardAlignments;
468    }
469   
470    /**
471    *
472    * @return true if the calculation was cancelled before completion
473    */
 
474  0 toggle public boolean isCancelled()
475    {
476  0 return cancelled;
477    }
478   
479    /**
480    * sends status updates to the progress bar for this panel
481    * @param type - PROGRESSMESSAGE or PROGRESSCOMPLETE
482    * @param message - the message (may be internationalised key)
483    */
 
484  0 toggle public void updateProgress(String type, String message)
485    {
486  0 firePropertyChange(type, "", MessageManager.getStringOrReturn("progress", message));
487    }
488    }