273261243a5caf061ee9bf527e6fb64859b1945c
[jalview.git] / src / jalview / appletgui / 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 \r
20 package jalview.appletgui;\r
21 \r
22 import java.util.*;\r
23 \r
24 import java.awt.event.*;\r
25 \r
26 import java.awt.*;\r
27 \r
28 import jalview.datamodel.*;\r
29 import jalview.appletgui.PaintRefresher;\r
30 \r
31 public class RedundancyPanel 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   Vector originalSequences;\r
37   Hashtable originalColours;\r
38   SequenceI[] oldAlignment;\r
39   float [] redundancy;\r
40   Frame frame;\r
41 \r
42   public RedundancyPanel(AlignmentPanel ap)\r
43   {\r
44     super(ap, 0, false, null);\r
45 \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(40);\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    * This is a copy of remove redundancy in jalivew.datamodel.Alignment\r
80    * except we dont want to remove redundancy, just calculate once\r
81    * so we can use the slider to dynamically hide redundant sequences\r
82    *\r
83    * @param threshold DOCUMENT ME!\r
84    * @param sel DOCUMENT ME!\r
85    *\r
86    * @return DOCUMENT ME!\r
87    */\r
88   public void run()\r
89   {\r
90       label.setText("Calculating....");\r
91 \r
92       slider.setVisible(false);\r
93       applyButton.setEnabled(false);\r
94       valueField.setVisible(false);\r
95 \r
96       validate();\r
97 \r
98       Vector sel = new Vector();\r
99       SequenceGroup sg = ap.av.getSelectionGroup();\r
100       int height;\r
101       originalSequences = new Vector();\r
102       originalColours = new Hashtable();\r
103 \r
104       if ( (sg != null) && (sg.getSize() >= 1))\r
105       {\r
106          height = sg.getSize();\r
107         for (int i = 0; i < sg.getSize(); i++)\r
108         {\r
109           sel.addElement(sg.getSequenceAt(i));\r
110         }\r
111       }\r
112       else\r
113       {\r
114         height = ap.av.alignment.getHeight();\r
115         for (int i = 0; i < ap.av.alignment.getHeight(); i++)\r
116         {\r
117           sel.addElement(ap.av.alignment.getSequenceAt(i));\r
118         }\r
119       }\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 \r
128      // long start = System.currentTimeMillis();\r
129 \r
130       float pid;\r
131       SequenceI seqi, seqj;\r
132       for (int i = 0; i < sel.size(); i++)\r
133       {\r
134           originalSequences.addElement(sel.elementAt(i));\r
135           originalColours.put(sel.elementAt(i),\r
136                              ((SequenceI) sel.elementAt(i)).getColor());\r
137 \r
138           for (int j = 0; j < i; j++)\r
139           {\r
140             if(i==j)\r
141               continue;\r
142 \r
143             seqi = (SequenceI) sel.elementAt(i);\r
144             seqj = (SequenceI) sel.elementAt(j);\r
145 \r
146             if (sg != null)\r
147             {\r
148               pid = jalview.util.Comparison.PID(seqi,\r
149                                                 seqj,\r
150                                                 sg.getStartRes(), sg.getEndRes());\r
151             }\r
152             else\r
153               pid = jalview.util.Comparison.PID( seqi,  seqj );\r
154 \r
155 \r
156             if(seqj.getLength() < seqi.getLength())\r
157               redundancy[j] = Math.max(pid, redundancy[j]);\r
158             else\r
159               redundancy[i] = Math.max(pid, redundancy[i]);\r
160 \r
161           }\r
162       }\r
163 \r
164 \r
165       label.setText("Enter the redundancy threshold");\r
166       slider.setVisible(true);\r
167       applyButton.setEnabled(true);\r
168       valueField.setVisible(true);\r
169 \r
170       validate();\r
171      // System.out.println("blob done "+ (System.currentTimeMillis()-start));\r
172   }\r
173 \r
174   void sliderValueChanged()\r
175   {\r
176     if(redundancy==null)\r
177       return;\r
178 \r
179     float value = slider.getValue();\r
180 \r
181     for(int i=0; i<redundancy.length; i++)\r
182     {\r
183       if (value > redundancy[i])\r
184          ((SequenceI)originalSequences.elementAt(i)).setColor(java.awt.Color.white);\r
185       else\r
186          ((SequenceI)originalSequences.elementAt(i)).setColor(java.awt.Color.red);\r
187     }\r
188 \r
189     PaintRefresher.Refresh(null,ap.av.alignment);\r
190 \r
191     }\r
192   public void applyButton_actionPerformed()\r
193   {\r
194     historyList.push(new HistoryItem("Remove redundancy",\r
195                         ap.av.alignment, HistoryItem.HIDE));\r
196 \r
197             if ((historyList.size() == 1) ||\r
198                     !ap.alignFrame.historyList.contains(historyList.firstElement()))\r
199             {\r
200                 ap.alignFrame.addHistoryItem((HistoryItem) historyList.firstElement());\r
201                 ap.alignFrame.updateEditMenuBar();\r
202             }\r
203 \r
204             Vector del = new Vector();\r
205 \r
206             undoButton.setEnabled(true);\r
207 \r
208             float value = slider.getValue();\r
209             SequenceGroup sg = ap.av.getSelectionGroup();\r
210 \r
211             for (int i = 0; i < redundancy.length; i++)\r
212             {\r
213               if (value <= redundancy[i])\r
214               {\r
215                 SequenceI seq = (SequenceI) originalSequences.elementAt(i);\r
216                 ap.av.alignment.deleteSequence(seq);\r
217                 del.addElement(seq);\r
218                 if (sg != null)\r
219                 {\r
220                   sg.deleteSequence(seq, false);\r
221                 }\r
222               }\r
223             }\r
224 \r
225 \r
226             // This has to be done before the restoreHistoryItem method of alignFrame will\r
227             // actually restore these sequences.\r
228             if (del.size() > 0)\r
229             {\r
230                 for (int i = 0, j = del.size(); i < j; i++)\r
231                 {\r
232                     SequenceI sq = (SequenceI) del.elementAt(i);\r
233                     sq.deleteChars(0, sq.getLength());\r
234                 }\r
235             }\r
236 \r
237         ap.av.firePropertyChange("alignment", null, ap.av.getAlignment().getSequences());\r
238         ap.alignFrame.updateEditMenuBar();\r
239 \r
240   }\r
241 \r
242   public void undoButton_actionPerformed()\r
243   {\r
244     HistoryItem hi = (HistoryItem) historyList.pop();\r
245     ap.alignFrame.restoreHistoryItem(hi);\r
246 \r
247     if (historyList.size() == 0)\r
248     {\r
249       undoButton.setEnabled(false);\r
250     }\r
251     ap.alignFrame.updateEditMenuBar();\r
252   }\r
253 \r
254   public void valueField_actionPerformed(ActionEvent e)\r
255   {\r
256     try\r
257     {\r
258       int i = Integer.parseInt(valueField.getText());\r
259       slider.setValue(i);\r
260     }\r
261     catch (Exception ex)\r
262     {\r
263       valueField.setText(slider.getValue() + "");\r
264     }\r
265   }\r
266 \r
267 \r
268   public void windowOpened(WindowEvent evt)\r
269   {}\r
270 \r
271   public void windowClosing(WindowEvent evt)\r
272   {\r
273     for(int i=0; i<originalSequences.size(); i++)\r
274     {\r
275       SequenceI seq = (SequenceI)originalSequences.elementAt(i);\r
276       seq.setColor( (java.awt.Color)originalColours.get(seq));\r
277     }\r
278 \r
279     PaintRefresher.Refresh(ap.av.alignment);\r
280   }\r
281 \r
282   public void windowClosed(WindowEvent evt)\r
283   {}\r
284 \r
285   public void windowActivated(WindowEvent evt)\r
286   {}\r
287   public void windowDeactivated(WindowEvent evt)\r
288   {}\r
289   public void windowIconified(WindowEvent evt)\r
290   {}\r
291   public void windowDeiconified(WindowEvent evt)\r
292   {}\r
293 }\r