sequences are private in SequenceGroup
[jalview.git] / src / jalview / gui / RedundancyPanel.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2005 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 package jalview.gui;\r
20 \r
21 import jalview.datamodel.*;\r
22 \r
23 import jalview.jbgui.*;\r
24 \r
25 import java.awt.event.*;\r
26 \r
27 import java.util.*;\r
28 \r
29 import javax.swing.event.*;\r
30 import jalview.util.Comparison;\r
31 import javax.swing.*;\r
32 \r
33 \r
34 /**\r
35  * DOCUMENT ME!\r
36  *\r
37  * @author $author$\r
38  * @version $Revision$\r
39  */\r
40 public class RedundancyPanel extends GSliderPanel implements Runnable\r
41 {\r
42     AlignFrame af;\r
43     AlignmentPanel ap;\r
44     Stack historyList = new Stack(); // simpler than synching with alignFrame.\r
45     float [] redundancy;\r
46     Vector originalSequences;\r
47     Hashtable originalColours;\r
48     JInternalFrame frame;\r
49 \r
50     /**\r
51      * Creates a new RedundancyPanel object.\r
52      *\r
53      * @param ap DOCUMENT ME!\r
54      * @param af DOCUMENT ME!\r
55      */\r
56     public RedundancyPanel(AlignmentPanel ap, AlignFrame af)\r
57     {\r
58         this.ap = ap;\r
59         this.af = af;\r
60 \r
61         slider.addChangeListener(new ChangeListener()\r
62             {\r
63                 public void stateChanged(ChangeEvent evt)\r
64                 {\r
65                     valueField.setText(slider.getValue() + "");\r
66                     sliderValueChanged();\r
67                 }\r
68             });\r
69 \r
70         applyButton.setText("Remove");\r
71         allGroupsCheck.setVisible(false);\r
72         slider.setMinimum(60);\r
73         slider.setMaximum(100);\r
74         slider.setValue(100);\r
75 \r
76         Thread worker = new Thread(this);\r
77         worker.start();\r
78 \r
79         frame = new JInternalFrame();\r
80         frame.setContentPane(this);\r
81         Desktop.addInternalFrame(frame, "Redundancy threshold selection", 400,\r
82                          100, false);\r
83         frame.addInternalFrameListener(new InternalFrameAdapter()\r
84             {\r
85               public void internalFrameClosing(InternalFrameEvent evt)\r
86               {\r
87                 resetColours();\r
88               }\r
89             }\r
90             );\r
91 \r
92     }\r
93 \r
94 \r
95     /**\r
96      * This is a copy of remove redundancy in jalivew.datamodel.Alignment\r
97      * except we dont want to remove redundancy, just calculate once\r
98      * so we can use the slider to dynamically hide redundant sequences\r
99      *\r
100      * @param threshold DOCUMENT ME!\r
101      * @param sel DOCUMENT ME!\r
102      *\r
103      * @return DOCUMENT ME!\r
104      */\r
105     public void run()\r
106     {\r
107         JProgressBar progress = new JProgressBar();\r
108         progress.setIndeterminate(true);\r
109         southPanel.add(progress, java.awt.BorderLayout.SOUTH);\r
110 \r
111         label.setText("Calculating....");\r
112 \r
113         slider.setVisible(false);\r
114         applyButton.setEnabled(false);\r
115         valueField.setVisible(false);\r
116 \r
117         validate();\r
118 \r
119         Vector sel = new Vector();\r
120         SequenceGroup sg = ap.av.getSelectionGroup();\r
121         int height;\r
122         originalSequences = new Vector();\r
123         originalColours = new Hashtable();\r
124 \r
125         if ( (sg != null) && (sg.getSize(false) >= 1))\r
126         {\r
127            height = sg.getSize(false);\r
128           for (int i = 0; i < sg.getSize(false); i++)\r
129           {\r
130             sel.addElement(sg.getSequenceAt(i));\r
131           }\r
132         }\r
133         else\r
134         {\r
135           height = ap.av.alignment.getHeight();\r
136           for (int i = 0; i < ap.av.alignment.getHeight(); i++)\r
137           {\r
138             sel.addElement(ap.av.alignment.getSequenceAt(i));\r
139           }\r
140         }\r
141 \r
142         redundancy = new float[height];\r
143         for (int i = 0; i < height; i++)\r
144         {\r
145           redundancy[i] = 0f;\r
146         }\r
147 \r
148 \r
149        // long start = System.currentTimeMillis();\r
150 \r
151         float pid;\r
152         SequenceI seqi, seqj;\r
153         for (int i = 0; i < sel.size(); i++)\r
154         {\r
155             originalSequences.addElement(sel.elementAt(i));\r
156             originalColours.put(sel.elementAt(i),\r
157                                ((SequenceI) sel.elementAt(i)).getColor());\r
158 \r
159             for (int j = 0; j < i; j++)\r
160             {\r
161               if(i==j)\r
162                 continue;\r
163 \r
164               seqi = (SequenceI) sel.elementAt(i);\r
165               seqj = (SequenceI) sel.elementAt(j);\r
166 \r
167               if (sg != null)\r
168                 pid = Comparison.PID( seqi,\r
169                                      seqj,\r
170                                      sg.getStartRes(), sg.getEndRes());\r
171               else\r
172                 pid = Comparison.PID( seqi,  seqj );\r
173 \r
174 \r
175               if(seqj.getLength() < seqi.getLength())\r
176                 redundancy[j] = Math.max(pid, redundancy[j]);\r
177               else\r
178                 redundancy[i] = Math.max(pid, redundancy[i]);\r
179 \r
180             }\r
181         }\r
182 \r
183 \r
184         progress.setIndeterminate(false);\r
185         progress.setVisible(false);\r
186         progress = null;\r
187 \r
188         label.setText("Enter the redundancy threshold");\r
189         slider.setVisible(true);\r
190         applyButton.setEnabled(true);\r
191         valueField.setVisible(true);\r
192 \r
193         validate();\r
194        // System.out.println("blob done "+ (System.currentTimeMillis()-start));\r
195     }\r
196 \r
197     void sliderValueChanged()\r
198     {\r
199       if(redundancy==null)\r
200         return;\r
201 \r
202       float value = slider.getValue();\r
203 \r
204       for(int i=0; i<redundancy.length; i++)\r
205       {\r
206         if (value > redundancy[i])\r
207            ((SequenceI)originalSequences.elementAt(i)).setColor(java.awt.Color.white);\r
208         else\r
209            ((SequenceI)originalSequences.elementAt(i)).setColor(java.awt.Color.red);\r
210       }\r
211 \r
212       PaintRefresher.Refresh(null,ap.av.alignment);\r
213 \r
214     }\r
215 \r
216     /**\r
217      * DOCUMENT ME!\r
218      *\r
219      * @param e DOCUMENT ME!\r
220      */\r
221     public void applyButton_actionPerformed(ActionEvent e)\r
222     {\r
223         historyList.push(new HistoryItem("Remove redundancy",\r
224                     ap.av.alignment, HistoryItem.HIDE));\r
225 \r
226         if ((historyList.size() == 1) ||\r
227                 !af.historyList.contains(historyList.firstElement()))\r
228         {\r
229             af.addHistoryItem((HistoryItem) historyList.firstElement());\r
230             af.updateEditMenuBar();\r
231         }\r
232 \r
233         Vector del = new Vector();\r
234 \r
235         undoButton.setEnabled(true);\r
236 \r
237         float value = slider.getValue();\r
238         SequenceGroup sg = ap.av.getSelectionGroup();\r
239 \r
240         for (int i = 0; i < redundancy.length; i++)\r
241         {\r
242           if (value <= redundancy[i])\r
243           {\r
244             SequenceI seq = (SequenceI) originalSequences.elementAt(i);\r
245             ap.av.alignment.deleteSequence(seq);\r
246             del.add(seq);\r
247             if (sg != null)\r
248             {\r
249               sg.deleteSequence(seq, false);\r
250             }\r
251           }\r
252         }\r
253 \r
254 \r
255         // This has to be done before the restoreHistoryItem method of alignFrame will\r
256         // actually restore these sequences.\r
257         if (del.size() > 0)\r
258         {\r
259             for (int i = 0, j = del.size(); i < j; i++)\r
260             {\r
261                 SequenceI sq = (SequenceI) del.elementAt(i);\r
262                 sq.deleteChars(0, sq.getLength());\r
263             }\r
264         }\r
265 \r
266         ap.av.firePropertyChange("alignment", null, ap.av.getAlignment().getSequences());\r
267         af.updateEditMenuBar();\r
268     }\r
269 \r
270     void resetColours()\r
271     {\r
272       for(int i=0; i<originalSequences.size(); i++)\r
273       {\r
274         SequenceI seq = (SequenceI)originalSequences.elementAt(i);\r
275         seq.setColor( (java.awt.Color)originalColours.get(seq));\r
276       }\r
277 \r
278       PaintRefresher.Refresh(ap.av.alignment);\r
279     }\r
280 \r
281     /**\r
282      * DOCUMENT ME!\r
283      *\r
284      * @param e DOCUMENT ME!\r
285      */\r
286     public void undoButton_actionPerformed(ActionEvent e)\r
287     {\r
288       HistoryItem hi = (HistoryItem) historyList.pop();\r
289       af.restoreHistoryItem(hi);\r
290 \r
291       if (historyList.size() == 0)\r
292       {\r
293         undoButton.setEnabled(false);\r
294 \r
295         if (af.historyList.contains(hi))\r
296         {\r
297           af.historyList.remove(hi);\r
298           af.updateEditMenuBar();\r
299         }\r
300       }\r
301     }\r
302 \r
303     /**\r
304      * DOCUMENT ME!\r
305      *\r
306      * @param e DOCUMENT ME!\r
307      */\r
308     public void valueField_actionPerformed(ActionEvent e)\r
309     {\r
310         try\r
311         {\r
312             int i = Integer.parseInt(valueField.getText());\r
313             slider.setValue(i);\r
314         }\r
315         catch (Exception ex)\r
316         {\r
317             valueField.setText(slider.getValue() + "");\r
318         }\r
319     }\r
320 \r
321 \r
322 }\r