2 * Jalview - A Sequence Alignment Editor and Viewer (Development Version 2.4.1)
3 * Copyright (C) 2009 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
23 import java.awt.event.*;
25 import javax.swing.event.*;
27 import jalview.commands.*;
28 import jalview.datamodel.*;
29 import jalview.jbgui.*;
30 import jalview.util.*;
38 public class RedundancyPanel extends GSliderPanel implements Runnable
44 Stack historyList = new Stack(); // simpler than synching with alignFrame.
48 SequenceI[] originalSequences;
55 * Creates a new RedundancyPanel object.
62 public RedundancyPanel(final AlignmentPanel ap, AlignFrame af)
66 redundantSeqs = new Vector();
68 slider.addChangeListener(new ChangeListener()
70 public void stateChanged(ChangeEvent evt)
72 valueField.setText(slider.getValue() + "");
77 applyButton.setText("Remove");
78 allGroupsCheck.setVisible(false);
80 slider.setMaximum(100);
83 Thread worker = new Thread(this);
86 frame = new JInternalFrame();
87 frame.setContentPane(this);
88 Desktop.addInternalFrame(frame, "Redundancy threshold selection", 400,
90 frame.addInternalFrameListener(new InternalFrameAdapter()
92 public void internalFrameClosing(InternalFrameEvent evt)
94 ap.idPanel.idCanvas.setHighlighted(null);
101 * This is a copy of remove redundancy in jalivew.datamodel.Alignment except
102 * we dont want to remove redundancy, just calculate once so we can use the
103 * slider to dynamically hide redundant sequences
110 * @return DOCUMENT ME!
114 JProgressBar progress = new JProgressBar();
115 progress.setIndeterminate(true);
116 southPanel.add(progress, java.awt.BorderLayout.SOUTH);
118 label.setText("Calculating....");
120 slider.setVisible(false);
121 applyButton.setEnabled(false);
122 valueField.setVisible(false);
126 String[] omitHidden = null;
128 SequenceGroup sg = ap.av.getSelectionGroup();
133 if ((sg != null) && (sg.getSize() >= 1))
135 originalSequences = sg.getSequencesInOrder(ap.av.alignment);
136 start = sg.getStartRes();
137 end = sg.getEndRes();
141 originalSequences = ap.av.alignment.getSequencesArray();
143 end = ap.av.alignment.getWidth();
146 height = originalSequences.length;
148 redundancy = new float[height];
149 for (int i = 0; i < height; i++)
154 if (ap.av.hasHiddenColumns)
156 omitHidden = ap.av.getViewAsString(sg != null);
159 // long start = System.currentTimeMillis();
163 for (int i = 0; i < height; i++)
166 for (int j = 0; j < i; j++)
173 if (omitHidden == null)
175 seqi = originalSequences[i].getSequenceAsString(start, end);
176 seqj = originalSequences[j].getSequenceAsString(start, end);
180 seqi = omitHidden[i];
181 seqj = omitHidden[j];
184 pid = Comparison.PID(seqi, seqj);
186 if (seqj.length() < seqi.length())
188 redundancy[j] = Math.max(pid, redundancy[j]);
192 redundancy[i] = Math.max(pid, redundancy[i]);
198 progress.setIndeterminate(false);
199 progress.setVisible(false);
202 label.setText("Enter the redundancy threshold");
203 slider.setVisible(true);
204 applyButton.setEnabled(true);
205 valueField.setVisible(true);
208 // System.out.println((System.currentTimeMillis()-start));
211 void sliderValueChanged()
213 if (redundancy == null)
218 float value = slider.getValue();
220 for (int i = 0; i < redundancy.length; i++)
222 if (value > redundancy[i])
224 redundantSeqs.remove(originalSequences[i]);
226 else if (!redundantSeqs.contains(originalSequences[i]))
228 redundantSeqs.add(originalSequences[i]);
233 ap.idPanel.idCanvas.setHighlighted(redundantSeqs);
242 public void applyButton_actionPerformed(ActionEvent e)
244 Vector del = new Vector();
246 undoButton.setEnabled(true);
248 float value = slider.getValue();
249 SequenceGroup sg = ap.av.getSelectionGroup();
251 for (int i = 0; i < redundancy.length; i++)
253 if (value <= redundancy[i])
255 del.addElement(originalSequences[i]);
259 // This has to be done before the restoreHistoryItem method of alignFrame
261 // actually restore these sequences.
264 SequenceI[] deleted = new SequenceI[del.size()];
267 for (int i = 0; i < del.size(); i++)
269 deleted[i] = (SequenceI) del.elementAt(i);
270 if (deleted[i].getLength() > width)
272 width = deleted[i].getLength();
276 EditCommand cut = new EditCommand("Remove Redundancy",
277 EditCommand.CUT, deleted, 0, width, ap.av.alignment);
279 for (int i = 0; i < del.size(); i++)
281 ap.av.alignment.deleteSequence(deleted[i]);
282 PaintRefresher.Refresh(this, ap.av.getSequenceSetId(), true, true);
285 sg.deleteSequence(deleted[i], false);
289 historyList.push(cut);
291 ap.alignFrame.addHistoryItem(cut);
293 ap.av.firePropertyChange("alignment", null, ap.av.getAlignment()
305 public void undoButton_actionPerformed(ActionEvent e)
307 CommandI command = (CommandI) historyList.pop();
308 command.undoCommand(af.getViewAlignments());
310 if (ap.av.historyList.contains(command))
312 ap.av.historyList.remove(command);
313 af.updateEditMenuBar();
316 ap.paintAlignment(true);
318 if (historyList.size() == 0)
320 undoButton.setEnabled(false);
330 public void valueField_actionPerformed(ActionEvent e)
334 int i = Integer.parseInt(valueField.getText());
336 } catch (Exception ex)
338 valueField.setText(slider.getValue() + "");