Use paintAlignment
[jalview.git] / src / jalview / appletgui / RedundancyPanel.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
4  *\r
5  * This program is free software; you can redistribute it and/or\r
6  * modify it under the terms of the GNU General Public License\r
7  * as published by the Free Software Foundation; either version 2\r
8  * of the License, or (at your option) any later version.\r
9  *\r
10  * This program is distributed in the hope that it will be useful,\r
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13  * GNU General Public License for more details.\r
14  *\r
15  * You should have received a copy of the GNU General Public License\r
16  * along with this program; if not, write to the Free Software\r
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
18  */\r
19 \r
20 package jalview.appletgui;\r
21 \r
22 import java.util.*;\r
23 \r
24 import java.awt.*;\r
25 import java.awt.event.*;\r
26 \r
27 import jalview.commands.*;\r
28 import jalview.datamodel.*;\r
29 \r
30 public class RedundancyPanel\r
31     extends SliderPanel implements Runnable, WindowListener\r
32 {\r
33   AlignmentPanel ap;\r
34 \r
35   Stack historyList = new Stack(); // simpler than synching with alignFrame.\r
36   float[] redundancy;\r
37   SequenceI[] originalSequences;\r
38   Frame frame;\r
39   Vector redundantSeqs;\r
40 \r
41   public RedundancyPanel(AlignmentPanel ap)\r
42   {\r
43     super(ap, 0, false, null);\r
44 \r
45     redundantSeqs = new Vector();\r
46     this.ap = ap;\r
47     undoButton.setVisible(true);\r
48     applyButton.setVisible(true);\r
49     allGroupsCheck.setVisible(false);\r
50 \r
51     label.setText("Enter the redundancy threshold");\r
52     valueField.setText("100");\r
53 \r
54     slider.setVisibleAmount(1);\r
55     slider.setMinimum(0);\r
56     slider.setMaximum(100 + slider.getVisibleAmount());\r
57     slider.setValue(100);\r
58 \r
59     slider.addAdjustmentListener(new AdjustmentListener()\r
60     {\r
61       public void adjustmentValueChanged(AdjustmentEvent evt)\r
62       {\r
63         valueField.setText(slider.getValue() + "");\r
64         sliderValueChanged();\r
65       }\r
66     });\r
67 \r
68     frame = new Frame();\r
69     frame.add(this);\r
70     jalview.bin.JalviewLite.addFrame(frame, "Redundancy threshold selection",\r
71                                      400, 100);\r
72 \r
73     frame.addWindowListener(this);\r
74 \r
75     Thread worker = new Thread(this);\r
76     worker.start();\r
77   }\r
78 \r
79   /**\r
80    * This is a copy of remove redundancy in jalivew.datamodel.Alignment\r
81    * except we dont want to remove redundancy, just calculate once\r
82    * so we can use the slider to dynamically hide redundant sequences\r
83    *\r
84    * @param threshold DOCUMENT ME!\r
85    * @param sel DOCUMENT ME!\r
86    *\r
87    * @return DOCUMENT ME!\r
88    */\r
89   public void run()\r
90   {\r
91     label.setText("Calculating....");\r
92 \r
93     slider.setVisible(false);\r
94     applyButton.setEnabled(false);\r
95     valueField.setVisible(false);\r
96 \r
97     validate();\r
98 \r
99     String[] omitHidden = null;\r
100 \r
101     SequenceGroup sg = ap.av.getSelectionGroup();\r
102     int height;\r
103 \r
104     int start, end;\r
105 \r
106     if ( (sg != null) && (sg.getSize() >= 1))\r
107     {\r
108       originalSequences = sg.getSequencesInOrder(ap.av.alignment);\r
109       start = sg.getStartRes();\r
110       end = sg.getEndRes();\r
111     }\r
112     else\r
113     {\r
114       originalSequences = ap.av.alignment.getSequencesArray();\r
115       start = 0;\r
116       end = ap.av.alignment.getWidth();\r
117     }\r
118 \r
119     height = originalSequences.length;\r
120 \r
121     redundancy = new float[height];\r
122     for (int i = 0; i < height; i++)\r
123     {\r
124       redundancy[i] = 0f;\r
125     }\r
126 \r
127     //  if (ap.av.hasHiddenColumns)\r
128     {\r
129       //   omitHidden = ap.av.getSelectionAsString();\r
130     }\r
131 \r
132     // long start = System.currentTimeMillis();\r
133 \r
134     float pid;\r
135     String seqi, seqj;\r
136     for (int i = 0; i < height; i++)\r
137     {\r
138       for (int j = 0; j < i; j++)\r
139       {\r
140         if (i == j)\r
141         {\r
142           continue;\r
143         }\r
144 \r
145         if (omitHidden == null)\r
146         {\r
147           seqi = originalSequences[i].getSequenceAsString(start, end);\r
148           seqj = originalSequences[j].getSequenceAsString(start, end);\r
149         }\r
150         else\r
151         {\r
152           seqi = omitHidden[i];\r
153           seqj = omitHidden[j];\r
154         }\r
155 \r
156         pid = jalview.util.Comparison.PID(seqi, seqj);\r
157 \r
158         if (seqj.length() < seqi.length())\r
159         {\r
160           redundancy[j] = Math.max(pid, redundancy[j]);\r
161         }\r
162         else\r
163         {\r
164           redundancy[i] = Math.max(pid, redundancy[i]);\r
165         }\r
166 \r
167       }\r
168     }\r
169 \r
170     label.setText("Enter the redundancy threshold");\r
171     slider.setVisible(true);\r
172     applyButton.setEnabled(true);\r
173     valueField.setVisible(true);\r
174 \r
175     validate();\r
176     // System.out.println("blob done "+ (System.currentTimeMillis()-start));\r
177   }\r
178 \r
179   void sliderValueChanged()\r
180   {\r
181     if (redundancy == null)\r
182     {\r
183       return;\r
184     }\r
185 \r
186     float value = slider.getValue();\r
187 \r
188     for (int i = 0; i < redundancy.length; i++)\r
189     {\r
190       if (value > redundancy[i])\r
191       {\r
192         redundantSeqs.removeElement(originalSequences[i]);\r
193       }\r
194       else if (!redundantSeqs.contains(originalSequences[i]))\r
195       {\r
196         redundantSeqs.addElement(originalSequences[i]);\r
197       }\r
198     }\r
199 \r
200     ap.idPanel.idCanvas.setHighlighted(redundantSeqs);\r
201     PaintRefresher.Refresh(this,\r
202                            ap.av.getSequenceSetId(),\r
203                            true,\r
204                            true);\r
205 \r
206   }\r
207 \r
208   public void applyButton_actionPerformed()\r
209   {\r
210     Vector del = new Vector();\r
211 \r
212     undoButton.setEnabled(true);\r
213 \r
214     float value = slider.getValue();\r
215     SequenceGroup sg = ap.av.getSelectionGroup();\r
216 \r
217     for (int i = 0; i < redundancy.length; i++)\r
218     {\r
219       if (value <= redundancy[i])\r
220       {\r
221         del.addElement(originalSequences[i]);\r
222       }\r
223     }\r
224 \r
225     // This has to be done before the restoreHistoryItem method of alignFrame will\r
226     // actually restore these sequences.\r
227     if (del.size() > 0)\r
228     {\r
229       SequenceI[] deleted = new SequenceI[del.size()];\r
230 \r
231       int width = 0;\r
232       for (int i = 0; i < del.size(); i++)\r
233       {\r
234         deleted[i] = (SequenceI) del.elementAt(i);\r
235         if (deleted[i].getLength() > width)\r
236         {\r
237           width = deleted[i].getLength();\r
238         }\r
239       }\r
240 \r
241       EditCommand cut = new EditCommand("Remove Redundancy",\r
242                                         EditCommand.CUT, deleted, 0, width,\r
243                                         ap.av.alignment);\r
244 \r
245       for (int i = 0; i < del.size(); i++)\r
246       {\r
247         ap.av.alignment.deleteSequence(deleted[i]);\r
248         PaintRefresher.Refresh(this,\r
249                                ap.av.getSequenceSetId(),\r
250                                true,\r
251                                true);\r
252         if (sg != null)\r
253         {\r
254           sg.deleteSequence(deleted[i], false);\r
255         }\r
256       }\r
257 \r
258       historyList.push(cut);\r
259 \r
260       ap.alignFrame.addHistoryItem(cut);\r
261 \r
262       ap.av.firePropertyChange("alignment", null,\r
263                                ap.av.getAlignment().getSequences());\r
264     }\r
265 \r
266   }\r
267 \r
268   public void undoButton_actionPerformed()\r
269   {\r
270     CommandI command = (CommandI) historyList.pop();\r
271     command.undoCommand();\r
272 \r
273     if (ap.av.historyList.contains(command))\r
274     {\r
275       ap.av.historyList.removeElement(command);\r
276       ap.alignFrame.updateEditMenuBar();\r
277     }\r
278 \r
279     ap.paintAlignment(true);\r
280 \r
281     if (historyList.size() == 0)\r
282     {\r
283       undoButton.setEnabled(false);\r
284     }\r
285   }\r
286 \r
287   public void valueField_actionPerformed(ActionEvent e)\r
288   {\r
289     try\r
290     {\r
291       int i = Integer.parseInt(valueField.getText());\r
292       slider.setValue(i);\r
293     }\r
294     catch (Exception ex)\r
295     {\r
296       valueField.setText(slider.getValue() + "");\r
297     }\r
298   }\r
299 \r
300   public void windowOpened(WindowEvent evt)\r
301   {}\r
302 \r
303   public void windowClosing(WindowEvent evt)\r
304   {\r
305     ap.idPanel.idCanvas.setHighlighted(null);\r
306   }\r
307 \r
308   public void windowClosed(WindowEvent evt)\r
309   {}\r
310 \r
311   public void windowActivated(WindowEvent evt)\r
312   {}\r
313 \r
314   public void windowDeactivated(WindowEvent evt)\r
315   {}\r
316 \r
317   public void windowIconified(WindowEvent evt)\r
318   {}\r
319 \r
320   public void windowDeiconified(WindowEvent evt)\r
321   {}\r
322 }\r