Clover icon

Coverage Report

  1. Project Clover database Thu Dec 4 2025 16:11:35 GMT
  2. Package jalview.gui

File PairwiseAlignPanel.java

 

Coverage histogram

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

Code metrics

46
126
24
1
483
307
50
0.4
5.25
24
2.08

Classes

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