header updated
[jalview.git] / src / jalview / appletgui / RedundancyPanel.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2006 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   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    * 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       String[] omitHidden = null;\r
99 \r
100       SequenceGroup sg = ap.av.getSelectionGroup();\r
101       int height;\r
102 \r
103       int start, end;\r
104 \r
105       if ( (sg != null) && (sg.getSize(false) >= 1))\r
106       {\r
107          originalSequences = sg.getSequencesInOrder(ap.av.alignment);\r
108          start = sg.getStartRes();\r
109          end = sg.getEndRes();\r
110       }\r
111       else\r
112       {\r
113         originalSequences = ap.av.alignment.getSequencesArray();\r
114         start = 0;\r
115         end = ap.av.alignment.getWidth();\r
116       }\r
117 \r
118       height = originalSequences.length;\r
119 \r
120       redundancy = new float[height];\r
121       for (int i = 0; i < height; i++)\r
122       {\r
123         redundancy[i] = 0f;\r
124       }\r
125 \r
126     //  if (ap.av.hasHiddenColumns)\r
127       {\r
128      //   omitHidden = ap.av.getSelectionAsString();\r
129       }\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               continue;\r
142 \r
143             if(omitHidden==null)\r
144             {\r
145               seqi = originalSequences[i].getSequence(start, end);\r
146               seqj = originalSequences[j].getSequence(start, end);\r
147             }\r
148             else\r
149             {\r
150               seqi = omitHidden[i];\r
151               seqj = omitHidden[j];\r
152             }\r
153 \r
154             pid = jalview.util.Comparison.PID( seqi,  seqj );\r
155 \r
156             if(seqj.length() < seqi.length())\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          redundantSeqs.removeElement(originalSequences[i]);\r
185       else if(!redundantSeqs.contains(originalSequences[i]))\r
186          redundantSeqs.addElement(originalSequences[i]);\r
187     }\r
188 \r
189     ap.idPanel.idCanvas.setHighlighted(redundantSeqs);\r
190 \r
191     PaintRefresher.Refresh(null,ap.av.alignment);\r
192 \r
193     }\r
194   public void applyButton_actionPerformed()\r
195   {\r
196     historyList.push(new HistoryItem("Remove redundancy",\r
197                         ap.av.alignment, HistoryItem.HIDE));\r
198 \r
199             if ((historyList.size() == 1) ||\r
200                     !ap.alignFrame.historyList.contains(historyList.firstElement()))\r
201             {\r
202                 ap.alignFrame.addHistoryItem((HistoryItem) historyList.firstElement());\r
203                 ap.alignFrame.updateEditMenuBar();\r
204             }\r
205 \r
206             Vector del = new Vector();\r
207 \r
208             undoButton.setEnabled(true);\r
209 \r
210             float value = slider.getValue();\r
211             SequenceGroup sg = ap.av.getSelectionGroup();\r
212 \r
213             for (int i = 0; i < redundancy.length; i++)\r
214             {\r
215               if (value <= redundancy[i])\r
216               {\r
217                 SequenceI seq = originalSequences[i];\r
218                 ap.av.alignment.deleteSequence(seq);\r
219                 del.addElement(seq);\r
220                 if (sg != null)\r
221                 {\r
222                   sg.deleteSequence(seq, false);\r
223                 }\r
224               }\r
225             }\r
226 \r
227 \r
228             // This has to be done before the restoreHistoryItem method of alignFrame will\r
229             // actually restore these sequences.\r
230             if (del.size() > 0)\r
231             {\r
232                 for (int i = 0, j = del.size(); i < j; i++)\r
233                 {\r
234                     SequenceI sq = (SequenceI) del.elementAt(i);\r
235                     sq.deleteChars(0, sq.getLength());\r
236                 }\r
237             }\r
238 \r
239         ap.av.firePropertyChange("alignment", null, ap.av.getAlignment().getSequences());\r
240         ap.alignFrame.updateEditMenuBar();\r
241 \r
242   }\r
243 \r
244   public void undoButton_actionPerformed()\r
245   {\r
246     HistoryItem hi = (HistoryItem) historyList.pop();\r
247     ap.alignFrame.restoreHistoryItem(hi);\r
248 \r
249     if (historyList.size() == 0)\r
250     {\r
251       undoButton.setEnabled(false);\r
252     }\r
253     ap.alignFrame.updateEditMenuBar();\r
254   }\r
255 \r
256   public void valueField_actionPerformed(ActionEvent e)\r
257   {\r
258     try\r
259     {\r
260       int i = Integer.parseInt(valueField.getText());\r
261       slider.setValue(i);\r
262     }\r
263     catch (Exception ex)\r
264     {\r
265       valueField.setText(slider.getValue() + "");\r
266     }\r
267   }\r
268 \r
269 \r
270   public void windowOpened(WindowEvent evt)\r
271   {}\r
272 \r
273   public void windowClosing(WindowEvent evt)\r
274   {\r
275     ap.idPanel.idCanvas.setHighlighted(null);\r
276   }\r
277 \r
278   public void windowClosed(WindowEvent evt)\r
279   {}\r
280 \r
281   public void windowActivated(WindowEvent evt)\r
282   {}\r
283   public void windowDeactivated(WindowEvent evt)\r
284   {}\r
285   public void windowIconified(WindowEvent evt)\r
286   {}\r
287   public void windowDeiconified(WindowEvent evt)\r
288   {}\r
289 }\r