From: Jim Procter Date: Sun, 27 Aug 2017 17:50:13 +0000 (+0100) Subject: Merge branch 'develop' into features/JAL-250_hideredundantseqs X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=refs%2Fheads%2Ffeatures%2FJAL-250_hideredundantseqs;hp=414c54986eb248b78432dc7b99956c6a2f20f018;p=jalview.git Merge branch 'develop' into features/JAL-250_hideredundantseqs --- diff --git a/src/jalview/analysis/AlignSeq.java b/src/jalview/analysis/AlignSeq.java index 34a21e6..98f257f 100755 --- a/src/jalview/analysis/AlignSeq.java +++ b/src/jalview/analysis/AlignSeq.java @@ -1057,8 +1057,18 @@ public class AlignSeq SequenceI[] originalSequences, String[] omitHidden, int start, int end, boolean ungapped) { + return (float[]) computeRedundancyMatrixWithRep(originalSequences, + omitHidden, start, end, ungapped)[0]; + } + + public static Object[] computeRedundancyMatrixWithRep( + SequenceI[] originalSequences, String[] omitHidden, int start, + int end, boolean ungapped) + { + int height = originalSequences.length; float[] redundancy = new float[height]; + SequenceI[] rep = new SequenceI[height]; int[] lngth = new int[height]; for (int i = 0; i < height; i++) { @@ -1115,15 +1125,23 @@ public class AlignSeq // use real sequence length rather than string length if (lngth[j] < lngth[i]) { - redundancy[j] = Math.max(pid, redundancy[j]); + if (pid > redundancy[j]) + { + rep[j] = originalSequences[i]; + redundancy[j] = pid; + } } else { - redundancy[i] = Math.max(pid, redundancy[i]); + if (pid > redundancy[i]) + { + rep[i] = originalSequences[j]; + redundancy[i] = pid; + } } } } - return redundancy; + return new Object[] { redundancy, rep }; } } diff --git a/src/jalview/api/AlignViewControllerI.java b/src/jalview/api/AlignViewControllerI.java index a7ec69e..04c1fd9 100644 --- a/src/jalview/api/AlignViewControllerI.java +++ b/src/jalview/api/AlignViewControllerI.java @@ -20,6 +20,7 @@ */ package jalview.api; +import jalview.datamodel.SequenceGroup; import jalview.io.DataSourceType; import java.util.List; @@ -100,6 +101,14 @@ public interface AlignViewControllerI boolean relaxedIdMatching); /** + * clear any group definitions in the current view and add a set of new group + * definitions with randomly generated colours + * + * @param gps + */ + void showRandomColoursForGroups(List gps); + + /** * mark columns containing highlighted regions (e.g. from search, structure * highlight, or a mouse over event in another viewer) * diff --git a/src/jalview/controller/AlignViewController.java b/src/jalview/controller/AlignViewController.java index dd05843..d303b0d 100644 --- a/src/jalview/controller/AlignViewController.java +++ b/src/jalview/controller/AlignViewController.java @@ -38,6 +38,7 @@ import jalview.io.FeaturesFile; import jalview.util.MessageManager; import java.awt.Color; +import java.util.Arrays; import java.util.BitSet; import java.util.List; @@ -103,29 +104,36 @@ public class AlignViewController implements AlignViewControllerI } if (gps != null) { - viewport.getAlignment().deleteAllGroups(); - viewport.clearSequenceColours(); - viewport.setSelectionGroup(null); - // set view properties for each group - for (int g = 0; g < gps.length; g++) - { - // gps[g].setShowunconserved(viewport.getShowUnconserved()); - gps[g].setshowSequenceLogo(viewport.isShowSequenceLogo()); - viewport.getAlignment().addGroup(gps[g]); - Color col = new Color((int) (Math.random() * 255), - (int) (Math.random() * 255), (int) (Math.random() * 255)); - col = col.brighter(); - for (SequenceI sq : gps[g].getSequences(null)) - { - viewport.setSequenceColour(sq, col); - } - } + showRandomColoursForGroups(Arrays.asList(gps)); + return true; } return false; } @Override + public void showRandomColoursForGroups(List gps) + { + viewport.getAlignment().deleteAllGroups(); + viewport.clearSequenceColours(); + viewport.setSelectionGroup(null); + // set view properties for each group + for (SequenceGroup sg : gps) + { + // gps[g].setShowunconserved(viewport.getShowUnconserved()); + sg.setshowSequenceLogo(viewport.isShowSequenceLogo()); + viewport.getAlignment().addGroup(sg); + Color col = new Color((int) (Math.random() * 255), + (int) (Math.random() * 255), (int) (Math.random() * 255)); + col = col.brighter(); + for (SequenceI sq : sg.getSequences(null)) + { + viewport.setSequenceColour(sq, col); + } + } + } + + @Override public boolean createGroup() { diff --git a/src/jalview/gui/RedundancyPanel.java b/src/jalview/gui/RedundancyPanel.java index 8bf2fba..37458a7 100755 --- a/src/jalview/gui/RedundancyPanel.java +++ b/src/jalview/gui/RedundancyPanel.java @@ -29,8 +29,10 @@ import jalview.datamodel.SequenceI; import jalview.jbgui.GSliderPanel; import jalview.util.MessageManager; +import java.awt.Color; import java.awt.event.ActionEvent; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Stack; import java.util.Vector; @@ -66,6 +68,8 @@ public class RedundancyPanel extends GSliderPanel implements Runnable Vector redundantSeqs; + private SequenceI[] redreps; + /** * Creates a new RedundancyPanel object. * @@ -90,7 +94,7 @@ public class RedundancyPanel extends GSliderPanel implements Runnable } }); - applyButton.setText(MessageManager.getString("action.remove")); + applyButton.setText(MessageManager.getString("action.hide")); allGroupsCheck.setVisible(false); slider.setMinimum(0); slider.setMaximum(100); @@ -168,9 +172,13 @@ public class RedundancyPanel extends GSliderPanel implements Runnable { omitHidden = ap.av.getViewAsString(sg != null); } - redundancy = AlignSeq.computeRedundancyMatrix(originalSequences, + Object rr[] = AlignSeq.computeRedundancyMatrixWithRep( + originalSequences, omitHidden, start, end, false); + redundancy = (float[]) rr[0]; + redreps = (SequenceI[]) rr[1]; + progress.setIndeterminate(false); progress.setVisible(false); progress = null; @@ -214,21 +222,103 @@ public class RedundancyPanel extends GSliderPanel implements Runnable @Override public void applyButton_actionPerformed(ActionEvent e) { - Vector del = new Vector(); undoButton.setEnabled(true); float value = slider.getValue(); SequenceGroup sg = ap.av.getSelectionGroup(); - + // delete_seqs(value, sg); + hide_seqs(value, sg); + } + private void hide_seqs(float value, SequenceGroup sg) + { + /** + * hash to look up the representative for a sequence + */ + HashMap rep = new HashMap(); + /** + * hash to collect lists of sequences represented by a sequence + */ + HashMap reps = new HashMap(); for (int i = 0; i < redundancy.length; i++) { if (value <= redundancy[i]) { - del.addElement(originalSequences[i]); + // does this sequence represent other sequences ? + SequenceGroup repset; + // is the representative also redundant ? + SequenceI repForI = rep.get(redreps[i]); + if (repForI==null) { + // the representative is still in the alignment. + // is it representing anything already ? + repset = reps.get(redreps[i]); + if (repset==null) + { + repset = new SequenceGroup(); + } + repset.addSequence(originalSequences[i], false); + rep.put(originalSequences[i], redreps[i]); + reps.put(redreps[i], repset); + // and save the representative sequence for originalSeq + repForI = redreps[i]; + } else { + // already hidden the representative for this sequence, so look up its redundant peers + repset = reps.get(repForI); + if (repset==null) + { + throw new Error("Implementation failure for redundancy set creation"); + } + // add the sequence to the peerset, and mark sequence's representative in hash + repset.addSequence(originalSequences[i], false); + rep.put(originalSequences[i], repForI); + } + // merge any sequences represented by this with its new containing group + SequenceGroup existingreps = reps.remove(originalSequences[i]); + if (existingreps!=null) + { + for (SequenceI sq:existingreps.getSequences()) + { + rep.put(sq, repForI); + repset.addSequence(sq, false); + } + } } } + int s = 0, e = ap.av.getAlignment().getWidth(); + if (sg != null) + { + s = sg.getStartRes(); + e = sg.getEndRes(); + } + List sgs = new ArrayList(); + for (SequenceI repseq: reps.keySet()) + { + sg = reps.get(repseq); + sg.addSequence(repseq, false); + sg.setSeqrep(repseq); + sg.setStartRes(s); + sg.setEndRes(e); + sgs.add(sg); + } + ap.alignFrame.avc.showRandomColoursForGroups(sgs); + for (SequenceI repseq : reps.keySet()) + { + sg = reps.get(repseq); + ap.av.hideRepSequences(repseq, sg); + } + } + + private void delete_seqs(float value, SequenceGroup sg) + { + ArrayList del = new ArrayList(); + for (int i = 0; i < redundancy.length; i++) + { + if (value <= redundancy[i]) + { + del.add(originalSequences[i]); + } + } // This has to be done before the restoreHistoryItem method of alignFrame // will // actually restore these sequences. @@ -239,7 +329,7 @@ public class RedundancyPanel extends GSliderPanel implements Runnable int width = 0; for (int i = 0; i < del.size(); i++) { - deleted[i] = (SequenceI) del.elementAt(i); + deleted[i] = del.get(i); if (deleted[i].getLength() > width) { width = deleted[i].getLength(); @@ -303,4 +393,23 @@ public class RedundancyPanel extends GSliderPanel implements Runnable } } + /** + * DOCUMENT ME! + * + * @param e + * DOCUMENT ME! + */ + @Override + public void valueField_actionPerformed(ActionEvent e) + { + try + { + int i = Integer.parseInt(valueField.getText()); + slider.setValue(i); + } catch (Exception ex) + { + valueField.setText(slider.getValue() + ""); + } + } + }