JAL-4159 disable the score model combo box when pasimap is selected
[jalview.git] / src / jalview / gui / PairwiseAlignPanel.java
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.datamodel.Alignment;
25 import jalview.datamodel.AlignmentView;
26 import jalview.datamodel.SequenceGroup;
27 import jalview.datamodel.SequenceI;
28 import jalview.jbgui.GPairwiseAlignPanel;
29 import jalview.util.MessageManager;
30 import jalview.viewmodel.AlignmentViewport;
31 import jalview.math.MiscMath;
32
33 import java.beans.PropertyChangeListener;
34 import java.awt.event.ActionEvent;
35 import java.util.Vector;
36 import javax.swing.event.SwingPropertyChangeSupport;
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   AlignmentViewport av;
58
59   Vector<SequenceI> sequences;
60
61   private String alignmentOutput;
62
63   private boolean suppressTextbox;
64  
65   private boolean discardAlignments;
66
67   private boolean endGaps;
68
69   // for listening
70   public static final String TOTAL = "total";
71
72   public static final String PROGRESS = "progress";
73
74   private int total;
75
76   private int progress;
77
78   private SequenceGroup selection;
79   /**
80    * input sequences
81    */
82   private SequenceI[] seqs=null;
83
84   /**
85    * Creates a new PairwiseAlignPanel object.
86    * 
87    * @param viewport
88    *          DOCUMENT ME!
89    * @param endGaps ~ toggle gaps and the beginning and end of sequences
90    */
91   public PairwiseAlignPanel(AlignmentViewport viewport)
92   {
93     this(viewport, null, false, 120, 20, true); // default penalties used in AlignSeq
94   }
95   public PairwiseAlignPanel(AlignmentViewport viewport, boolean endGaps, int gapOpenCost, int gapExtendCost)
96   {
97     this(viewport, null, endGaps, gapOpenCost, gapExtendCost, true);
98   }
99
100   public PairwiseAlignPanel(AlignmentViewport viewport, SequenceGroup selection, boolean  endGaps,
101           int gapOpenCost, int gapExtendCost, boolean run)
102   {
103     super();
104     this.av = viewport;
105     this.GAP_OPEN_COST = gapOpenCost;
106     this.GAP_EXTEND_COST = gapExtendCost;
107     this.endGaps = endGaps;
108     this.selection = selection;
109     this.total = MiscMath.combinations(av.getAlignment().getHeight(), 2);
110
111     if (run)
112       calculate();
113     System.out.println("Creating pap");
114   }
115   
116   public void calculate()
117   {
118
119     StringBuilder sb = new StringBuilder(1024);
120
121     sequences = new Vector<SequenceI>();
122     String[] seqStrings;
123     seqs=null;
124
125     if (selection != null)
126     {
127       // given a set of sequences to compare
128       seqs = selection.getSelectionAsNewSequences(av.getAlignment());
129       seqStrings = new String[seqs.length];
130       int s = 0;
131       for (SequenceI seq : seqs)
132       {
133         seqStrings[s++] = seq.getSequenceAsString();
134       }
135     }
136     else
137     {
138       SequenceGroup selectionGroup = av.getSelectionGroup();
139       boolean isSelection = selectionGroup != null
140               && selectionGroup.getSize() > 0;
141       AlignmentView view = av.getAlignmentView(isSelection);
142       seqStrings = view.getSequenceStrings(av.getGapCharacter());
143       if (isSelection)
144       {
145         seqs = (SequenceI[]) view
146                 .getAlignmentAndHiddenColumns(av.getGapCharacter())[0];
147       }
148       else
149       {
150         seqs = av.getAlignment().getSequencesArray();
151       }
152     }
153     
154     String type = (av.getAlignment().isNucleotide()) ? AlignSeq.DNA
155             : AlignSeq.PEP;
156
157     float[][] scores = new float[seqs.length][seqs.length];
158     float[][] alignmentScores = new float[seqs.length][seqs.length];
159     double totscore = 0D;
160     int count = seqs.length;
161     suppressTextbox = count<10;
162     discardAlignments = count<15;
163     boolean first = true;
164
165     progress = 0;
166     firePropertyChange(TOTAL, 0, total);
167
168     suppressTextbox = count<10;
169     discardAlignments = count<15;
170
171     for (int i = 1; i < count; i++)
172     {
173       // fill diagonal alignmentScores with Float.NaN
174       alignmentScores[i - 1][i - 1] = Float.NaN;
175       for (int j = 0; j < i; j++)
176       {
177         AlignSeq as = new AlignSeq(seqs[i], seqStrings[i], seqs[j],
178                 seqStrings[j], type, GAP_OPEN_COST, GAP_EXTEND_COST);
179
180         if (as.s1str.length() == 0 || as.s2str.length() == 0)
181         {
182           continue;
183         }
184
185         as.calcScoreMatrix();
186         if (endGaps)
187         {
188           as.traceAlignmentWithEndGaps();
189         }
190         else
191         {
192           as.traceAlignment();
193         }
194         as.scoreAlignment();
195
196         if (!first)
197         {
198           jalview.bin.Console.outPrintln(DASHES);
199           textarea.append(DASHES);
200           sb.append(DASHES);
201         }
202         first = false;
203         if (discardAlignments) {
204           as.printAlignment(System.out);
205         }
206         scores[i][j] = as.getMaxScore() / as.getASeq1().length;
207         alignmentScores[i][j] = as.getAlignmentScore();
208         totscore = totscore + scores[i][j];
209         if (suppressTextbox)
210         {
211           textarea.append(as.getOutput());
212           sb.append(as.getOutput());
213         }
214         if (discardAlignments)
215         {
216           sequences.add(as.getAlignedSeq1());
217           sequences.add(as.getAlignedSeq2());
218         }
219         firePropertyChange(PROGRESS, progress, ++progress);
220       }
221     }
222     alignmentScores[count - 1][count - 1] = Float.NaN;
223
224     this.scores = scores;
225     this.alignmentScores = alignmentScores;
226
227     if (count > 2)
228     {
229       printScoreMatrix(seqs, scores, totscore);
230     }
231
232     alignmentOutput = sb.toString();
233   }
234
235   public float[][] getScores()
236   {
237     return this.scores;
238   }
239
240   public float[][] getAlignmentScores()
241   {
242     return this.alignmentScores;
243   }
244
245   public String getAlignmentOutput()
246   {
247     return this.alignmentOutput;
248   }
249
250   /**
251    * Prints a matrix of seqi-seqj pairwise alignment scores to sysout
252    * 
253    * @param seqs
254    * @param scores
255    * @param totscore
256    */
257   protected void printScoreMatrix(SequenceI[] seqs, float[][] scores,
258           double totscore)
259   {
260     System.out
261             .println("Pairwise alignment scaled similarity score matrix\n");
262
263     for (int i = 0; i < seqs.length; i++)
264     {
265       jalview.bin.Console.outPrintln(
266               String.format("%3d %s", i + 1, seqs[i].getDisplayId(true)));
267     }
268
269     /*
270      * table heading columns for sequences 1, 2, 3...
271      */
272     System.out.print("\n ");
273     for (int i = 0; i < seqs.length; i++)
274     {
275       System.out.print(String.format("%7d", i + 1));
276     }
277     jalview.bin.Console.outPrintln();
278
279     for (int i = 0; i < seqs.length; i++)
280     {
281       System.out.print(String.format("%3d", i + 1));
282       for (int j = 0; j < i; j++)
283       {
284         /*
285          * as a fraction of tot score, outputs are 0 <= score <= 1
286          */
287         System.out.print(String.format("%7.3f", scores[i][j] / totscore));
288       }
289       jalview.bin.Console.outPrintln();
290     }
291
292     jalview.bin.Console.outPrintln("\n");
293   }
294
295   /**
296    * DOCUMENT ME!
297    * 
298    * @param e
299    *          DOCUMENT ME!
300    */
301   @Override
302   protected void viewInEditorButton_actionPerformed(ActionEvent e)
303   {
304     SequenceI[] seq = new SequenceI[sequences.size()];
305
306     for (int i = 0; i < sequences.size(); i++)
307     {
308       seq[i] = sequences.elementAt(i);
309     }
310
311     AlignFrame af = new AlignFrame(new Alignment(seq),
312             AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
313
314     Desktop.addInternalFrame(af,
315             MessageManager.getString("label.pairwise_aligned_sequences"),
316             AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
317   }
318
319   public long getTotal()
320   {
321     return total;
322   }
323
324   public long getProgress()
325   {
326     return progress;
327   }
328   public SequenceI[] getInputSequences()
329   {
330     return seqs;
331   }
332 }