2 * Jalview - A Sequence Alignment Editor and Viewer
3 * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
21 import jalview.datamodel.*;
23 import jalview.jbgui.*;
25 import java.awt.event.*;
29 import javax.swing.event.*;
30 import jalview.util.Comparison;
40 public class RedundancyPanel extends GSliderPanel implements Runnable
44 Stack historyList = new Stack(); // simpler than synching with alignFrame.
46 SequenceI [] originalSequences;
51 * Creates a new RedundancyPanel object.
53 * @param ap DOCUMENT ME!
54 * @param af DOCUMENT ME!
56 public RedundancyPanel(final AlignmentPanel ap, AlignFrame af)
60 redundantSeqs = new Vector();
62 slider.addChangeListener(new ChangeListener()
64 public void stateChanged(ChangeEvent evt)
66 valueField.setText(slider.getValue() + "");
71 applyButton.setText("Remove");
72 allGroupsCheck.setVisible(false);
74 slider.setMaximum(100);
77 Thread worker = new Thread(this);
80 frame = new JInternalFrame();
81 frame.setContentPane(this);
82 Desktop.addInternalFrame(frame, "Redundancy threshold selection", 400,
84 frame.addInternalFrameListener(new InternalFrameAdapter()
86 public void internalFrameClosing(InternalFrameEvent evt)
88 ap.idPanel.idCanvas.setHighlighted(null);
97 * This is a copy of remove redundancy in jalivew.datamodel.Alignment
98 * except we dont want to remove redundancy, just calculate once
99 * so we can use the slider to dynamically hide redundant sequences
101 * @param threshold DOCUMENT ME!
102 * @param sel DOCUMENT ME!
104 * @return DOCUMENT ME!
108 JProgressBar progress = new JProgressBar();
109 progress.setIndeterminate(true);
110 southPanel.add(progress, java.awt.BorderLayout.SOUTH);
112 label.setText("Calculating....");
114 slider.setVisible(false);
115 applyButton.setEnabled(false);
116 valueField.setVisible(false);
120 String[] omitHidden = null;
122 SequenceGroup sg = ap.av.getSelectionGroup();
127 if ( (sg != null) && (sg.getSize(false) >= 1))
129 originalSequences = sg.getSequencesInOrder(ap.av.alignment);
130 start = sg.getStartRes();
131 end = sg.getEndRes();
135 originalSequences = ap.av.alignment.getSequencesArray();
137 end = ap.av.alignment.getWidth();
140 height = originalSequences.length;
142 redundancy = new float[height];
143 for (int i = 0; i < height; i++)
148 if (ap.av.hasHiddenColumns)
150 omitHidden = ap.av.getViewAsString(sg!=null);
154 // long start = System.currentTimeMillis();
158 for (int i = 0; i < height; i++)
161 for (int j = 0; j < i; j++)
168 seqi = originalSequences[i].getSequence(start, end);
169 seqj = originalSequences[j].getSequence(start, end);
173 seqi = omitHidden[i];
174 seqj = omitHidden[j];
177 pid = Comparison.PID( seqi, seqj );
179 if(seqj.length() < seqi.length())
180 redundancy[j] = Math.max(pid, redundancy[j]);
182 redundancy[i] = Math.max(pid, redundancy[i]);
187 progress.setIndeterminate(false);
188 progress.setVisible(false);
191 label.setText("Enter the redundancy threshold");
192 slider.setVisible(true);
193 applyButton.setEnabled(true);
194 valueField.setVisible(true);
197 // System.out.println((System.currentTimeMillis()-start));
200 void sliderValueChanged()
205 float value = slider.getValue();
207 for(int i=0; i<redundancy.length; i++)
209 if (value > redundancy[i])
210 redundantSeqs.remove(originalSequences[i]);
211 else if(!redundantSeqs.contains(originalSequences[i]))
212 redundantSeqs.add(originalSequences[i]);
216 ap.idPanel.idCanvas.setHighlighted(redundantSeqs);
222 * @param e DOCUMENT ME!
224 public void applyButton_actionPerformed(ActionEvent e)
226 historyList.push(new HistoryItem("Remove redundancy",
227 ap.av.alignment, HistoryItem.HIDE));
229 if ((historyList.size() == 1) ||
230 !af.historyList.contains(historyList.firstElement()))
232 af.addHistoryItem((HistoryItem) historyList.firstElement());
233 af.updateEditMenuBar();
236 Vector del = new Vector();
238 undoButton.setEnabled(true);
240 float value = slider.getValue();
241 SequenceGroup sg = ap.av.getSelectionGroup();
243 for (int i = 0; i < redundancy.length; i++)
245 if (value <= redundancy[i])
247 SequenceI seq = originalSequences[i];
248 ap.av.alignment.deleteSequence(seq);
252 sg.deleteSequence(seq, false);
258 // This has to be done before the restoreHistoryItem method of alignFrame will
259 // actually restore these sequences.
262 for (int i = 0, j = del.size(); i < j; i++)
264 SequenceI sq = (SequenceI) del.elementAt(i);
265 sq.deleteChars(0, sq.getLength());
269 ap.av.firePropertyChange("alignment", null, ap.av.getAlignment().getSequences());
270 af.updateEditMenuBar();
277 * @param e DOCUMENT ME!
279 public void undoButton_actionPerformed(ActionEvent e)
281 HistoryItem hi = (HistoryItem) historyList.pop();
282 af.restoreHistoryItem(hi);
284 if (historyList.size() == 0)
286 undoButton.setEnabled(false);
288 if (af.historyList.contains(hi))
290 af.historyList.remove(hi);
291 af.updateEditMenuBar();
299 * @param e DOCUMENT ME!
301 public void valueField_actionPerformed(ActionEvent e)
305 int i = Integer.parseInt(valueField.getText());
310 valueField.setText(slider.getValue() + "");