From 10ff37d2cb03f342ddbed679951d3e2fef0a404b Mon Sep 17 00:00:00 2001 From: gmungoc Date: Tue, 3 Feb 2015 10:53:56 +0000 Subject: [PATCH] JAL-845 code/refactoring/tests related to linking DNA and protein --- src/jalview/analysis/AlignSeq.java | 20 +- src/jalview/analysis/AlignmentUtils.java | 9 +- src/jalview/api/AlignViewportI.java | 17 +- src/jalview/appletgui/AlignFrame.java | 4 +- src/jalview/appletgui/AnnotationLabels.java | 37 +++- src/jalview/appletgui/ScalePanel.java | 30 ++- src/jalview/appletgui/SeqCanvas.java | 23 ++- src/jalview/bin/JalviewLite.java | 8 +- src/jalview/datamodel/Alignment.java | 86 ++------- src/jalview/datamodel/AlignmentI.java | 122 ++++++------ src/jalview/datamodel/CigarArray.java | 12 +- src/jalview/datamodel/ColumnSelection.java | 202 ++++++++++---------- src/jalview/datamodel/SearchResults.java | 84 ++++++-- src/jalview/datamodel/Sequence.java | 8 +- src/jalview/datamodel/SequenceI.java | 3 +- src/jalview/gui/AlignFrame.java | 68 +++---- src/jalview/gui/AlignViewport.java | 13 +- src/jalview/gui/AnnotationColourChooser.java | 5 +- src/jalview/gui/AnnotationLabels.java | 3 +- src/jalview/gui/CutAndPasteHtmlTransfer.java | 5 +- src/jalview/gui/Desktop.java | 11 +- src/jalview/gui/FeatureSettings.java | 3 +- src/jalview/gui/IdPanel.java | 3 + src/jalview/gui/Jalview2XML.java | 18 +- src/jalview/gui/PCAPanel.java | 3 +- src/jalview/gui/PairwiseAlignPanel.java | 5 +- src/jalview/gui/RotatableCanvas.java | 3 +- src/jalview/gui/ScalePanel.java | 37 ++-- src/jalview/gui/SeqCanvas.java | 6 +- src/jalview/gui/SeqPanel.java | 53 ++--- src/jalview/gui/SplitFrame.java | 146 +++++++++++++- src/jalview/gui/TreeCanvas.java | 23 +-- src/jalview/gui/TreePanel.java | 5 +- src/jalview/gui/VamsasApplication.java | 10 +- src/jalview/io/VamsasAppDatastore.java | 74 ++++--- src/jalview/io/vamsas/Sequencemapping.java | 23 +-- src/jalview/io/vamsas/Tree.java | 6 +- src/jalview/javascript/JsSelectionSender.java | 4 +- src/jalview/jbgui/GAlignFrame.java | 50 ++++- .../structure/StructureSelectionManager.java | 42 ++-- src/jalview/util/Comparison.java | 11 +- src/jalview/util/MappingUtils.java | 157 ++++++++++++--- src/jalview/util/ShiftList.java | 31 +-- src/jalview/viewmodel/AlignmentViewport.java | 44 ++++- src/jalview/ws/AWSThread.java | 15 +- test/jalview/analysis/AlignmentUtilsTests.java | 28 +-- test/jalview/analysis/TestAlignSeq.java | 13 +- test/jalview/datamodel/ColumnSelectionTest.java | 48 +++++ test/jalview/datamodel/SequenceTest.java | 45 +++++ test/jalview/util/ShiftListTest.java | 35 ++++ 50 files changed, 1111 insertions(+), 600 deletions(-) create mode 100644 test/jalview/datamodel/ColumnSelectionTest.java create mode 100644 test/jalview/util/ShiftListTest.java diff --git a/src/jalview/analysis/AlignSeq.java b/src/jalview/analysis/AlignSeq.java index ba7e520..ab03668 100755 --- a/src/jalview/analysis/AlignSeq.java +++ b/src/jalview/analysis/AlignSeq.java @@ -804,19 +804,23 @@ public class AlignSeq } /** - * DOCUMENT ME! + * Returns the given sequence with all of the given gap characters removed. * - * @param gapChar - * DOCUMENT ME! + * @param gapChars + * a string of characters to be treated as gaps * @param seq - * DOCUMENT ME! + * the input sequence * - * @return DOCUMENT ME! + * @return */ - public static String extractGaps(String gapChar, String seq) + public static String extractGaps(String gapChars, String seq) { - StringTokenizer str = new StringTokenizer(seq, gapChar); - StringBuffer newString = new StringBuffer(); + if (gapChars == null || seq == null) + { + return null; + } + StringTokenizer str = new StringTokenizer(seq, gapChars); + StringBuilder newString = new StringBuilder(seq.length()); while (str.hasMoreTokens()) { diff --git a/src/jalview/analysis/AlignmentUtils.java b/src/jalview/analysis/AlignmentUtils.java index f3e126d..7116af9 100644 --- a/src/jalview/analysis/AlignmentUtils.java +++ b/src/jalview/analysis/AlignmentUtils.java @@ -31,6 +31,7 @@ import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Set; /** * grab bag of useful alignment manipulation operations Expect these to be @@ -276,12 +277,12 @@ public class AlignmentUtils * Answers true if the mappings include one between the given (dataset) * sequences. */ - public static boolean mappingExists(AlignedCodonFrame[] codonFrames, + public static boolean mappingExists(Set set, SequenceI aaSeq, SequenceI cdnaSeq) { - if (codonFrames != null) + if (set != null) { - for (AlignedCodonFrame acf : codonFrames) + for (AlignedCodonFrame acf : set) { if (cdnaSeq == acf.getDnaForAaSeq(aaSeq)) { @@ -383,7 +384,7 @@ public class AlignmentUtils */ // TODO there may be one AlignedCodonFrame per dataset sequence, or one with // all mappings. Would it help to constrain this? - AlignedCodonFrame[] mappings = al.getCodonFrame(seq); + List mappings = al.getCodonFrame(seq); if (mappings == null) { return false; diff --git a/src/jalview/api/AlignViewportI.java b/src/jalview/api/AlignViewportI.java index 6753a29..798e47e 100644 --- a/src/jalview/api/AlignViewportI.java +++ b/src/jalview/api/AlignViewportI.java @@ -201,12 +201,19 @@ public interface AlignViewportI boolean selectedOnly); /** - * Returns a viewport which is a 'slave of' this one i.e. updated in - * tandem in some sense, or null if none is set. + * Returns a viewport which holds the cDna for this (protein), or vice versa, + * or null if none is set. * * @return */ - AlignViewportI getSlave(); - - void setSlave(AlignViewportI sl); + AlignViewportI getCodingComplement(); + + void setCodingComplement(AlignViewportI sl); + + /** + * Answers true if viewport hosts DNA/RAN, false if peptide. + * + * @return + */ + boolean isNucleotide(); } diff --git a/src/jalview/appletgui/AlignFrame.java b/src/jalview/appletgui/AlignFrame.java index ed64215..3cdfcc6 100644 --- a/src/jalview/appletgui/AlignFrame.java +++ b/src/jalview/appletgui/AlignFrame.java @@ -1690,8 +1690,8 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, for (int i = 0; i < viewport.getColumnSelection().getHiddenColumns() .size(); i++) { - int[] region = (int[]) viewport.getColumnSelection() - .getHiddenColumns().elementAt(i); + int[] region = viewport.getColumnSelection() + .getHiddenColumns().get(i); copiedHiddenColumns.addElement(new int[] { region[0] - hiddenOffset, region[1] - hiddenOffset }); diff --git a/src/jalview/appletgui/AnnotationLabels.java b/src/jalview/appletgui/AnnotationLabels.java index 3e81664..9fcf269 100755 --- a/src/jalview/appletgui/AnnotationLabels.java +++ b/src/jalview/appletgui/AnnotationLabels.java @@ -20,14 +20,36 @@ */ package jalview.appletgui; -import java.util.*; -import java.awt.*; -import java.awt.event.*; - -import jalview.datamodel.*; +import jalview.datamodel.AlignmentAnnotation; +import jalview.datamodel.Annotation; +import jalview.datamodel.SequenceGroup; +import jalview.datamodel.SequenceI; import jalview.util.MessageManager; import jalview.util.ParseHtmlBodyAndLinks; +import java.awt.Checkbox; +import java.awt.CheckboxMenuItem; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.FontMetrics; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.MenuItem; +import java.awt.Panel; +import java.awt.PopupMenu; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.InputEvent; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; +import java.util.Arrays; +import java.util.Vector; + public class AnnotationLabels extends Panel implements ActionListener, MouseListener, MouseMotionListener { @@ -221,7 +243,9 @@ public class AnnotationLabels extends Panel implements ActionListener, return true; } else + { return false; + } } @@ -715,8 +739,7 @@ public class AnnotationLabels extends Panel implements ActionListener, jalview.appletgui.AlignFrame.copiedHiddenColumns = new Vector(); for (int i = 0; i < av.getColumnSelection().getHiddenColumns().size(); i++) { - int[] region = (int[]) av.getColumnSelection().getHiddenColumns() - .elementAt(i); + int[] region = av.getColumnSelection().getHiddenColumns().get(i); jalview.appletgui.AlignFrame.copiedHiddenColumns .addElement(new int[] diff --git a/src/jalview/appletgui/ScalePanel.java b/src/jalview/appletgui/ScalePanel.java index 60d89aa..f32454b 100755 --- a/src/jalview/appletgui/ScalePanel.java +++ b/src/jalview/appletgui/ScalePanel.java @@ -20,12 +20,23 @@ */ package jalview.appletgui; -import java.awt.*; -import java.awt.event.*; - -import jalview.datamodel.*; +import jalview.datamodel.ColumnSelection; +import jalview.datamodel.SequenceGroup; import jalview.util.MessageManager; +import java.awt.Color; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.MenuItem; +import java.awt.Panel; +import java.awt.PopupMenu; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.InputEvent; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; + public class ScalePanel extends Panel implements MouseMotionListener, MouseListener { @@ -325,8 +336,7 @@ public class ScalePanel extends Panel implements MouseMotionListener, reveal = null; for (int i = 0; i < av.getColumnSelection().getHiddenColumns().size(); i++) { - int[] region = (int[]) av.getColumnSelection().getHiddenColumns() - .elementAt(i); + int[] region = av.getColumnSelection().getHiddenColumns().get(i); if (res + 1 == region[0] || res - 1 == region[1]) { reveal = region; @@ -407,18 +417,18 @@ public class ScalePanel extends Panel implements MouseMotionListener, } gg.drawLine( - (int) (((i - startx - 1) * av.charWidth) + (av.charWidth / 2)), + ((i - startx - 1) * av.charWidth) + (av.charWidth / 2), y + 2, - (int) (((i - startx - 1) * av.charWidth) + (av.charWidth / 2)), + ((i - startx - 1) * av.charWidth) + (av.charWidth / 2), y + (fm.getDescent() * 2)); } else { gg.drawLine( - (int) (((i - startx - 1) * av.charWidth) + (av.charWidth / 2)), + ((i - startx - 1) * av.charWidth) + (av.charWidth / 2), y + fm.getDescent(), - (int) (((i - startx - 1) * av.charWidth) + (av.charWidth / 2)), + ((i - startx - 1) * av.charWidth) + (av.charWidth / 2), y + (fm.getDescent() * 2)); } } diff --git a/src/jalview/appletgui/SeqCanvas.java b/src/jalview/appletgui/SeqCanvas.java index 33caf53..9c2fd73 100755 --- a/src/jalview/appletgui/SeqCanvas.java +++ b/src/jalview/appletgui/SeqCanvas.java @@ -20,9 +20,17 @@ */ package jalview.appletgui; -import java.awt.*; - -import jalview.datamodel.*; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.SearchResults; +import jalview.datamodel.SequenceGroup; +import jalview.datamodel.SequenceI; + +import java.awt.Color; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Panel; +import java.util.List; public class SeqCanvas extends Panel { @@ -516,15 +524,14 @@ public class SeqCanvas extends Panel } else { - java.util.Vector regions = av.getColumnSelection().getHiddenColumns(); + List regions = av.getColumnSelection().getHiddenColumns(); int screenY = 0; int blockStart = startRes; int blockEnd = endRes; - for (int i = 0; i < regions.size(); i++) + for (int[] region : regions) { - int[] region = (int[]) regions.elementAt(i); int hideStart = region[0]; int hideEnd = region[1]; @@ -646,7 +653,7 @@ public class SeqCanvas extends Panel if ((group == null) && (av.getAlignment().getGroups().size() > 0)) { - group = (SequenceGroup) av.getAlignment().getGroups().get(0); + group = av.getAlignment().getGroups().get(0); groupIndex = 0; } @@ -803,7 +810,7 @@ public class SeqCanvas extends Panel break; } - group = (SequenceGroup) av.getAlignment().getGroups() + group = av.getAlignment().getGroups() .get(groupIndex); } while (groupIndex < av.getAlignment().getGroups().size()); diff --git a/src/jalview/bin/JalviewLite.java b/src/jalview/bin/JalviewLite.java index ae8bc98..f596a9c 100644 --- a/src/jalview/bin/JalviewLite.java +++ b/src/jalview/bin/JalviewLite.java @@ -60,6 +60,7 @@ import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URL; import java.util.Hashtable; +import java.util.List; import java.util.StringTokenizer; import java.util.Vector; @@ -447,12 +448,11 @@ public class JalviewLite extends Applet implements end = rs.findIndex(end); if (csel != null) { - Vector cs = csel.getSelected(); + List cs = csel.getSelected(); csel.clear(); - for (int csi = 0, csiS = cs.size(); csi < csiS; csi++) + for (Integer selectedCol : cs) { - csel.addElement(rs.findIndex(((Integer) cs.elementAt(csi)) - .intValue())); + csel.addElement(rs.findIndex(selectedCol)); } } } diff --git a/src/jalview/datamodel/Alignment.java b/src/jalview/datamodel/Alignment.java index 5c2bc22..f660697 100755 --- a/src/jalview/datamodel/Alignment.java +++ b/src/jalview/datamodel/Alignment.java @@ -28,6 +28,7 @@ import java.util.ArrayList; import java.util.Enumeration; import java.util.HashSet; import java.util.Hashtable; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -255,10 +256,9 @@ public class Alignment implements AlignmentI @Override public void setSequenceAt(int i, SequenceI snew) { - SequenceI oldseq = getSequenceAt(i); - deleteSequence(i); synchronized (sequences) { + deleteSequence(i); sequences.set(i, snew); } } @@ -327,8 +327,8 @@ public class Alignment implements AlignmentI synchronized (sequences) { sequences.remove(i); + hiddenSequences.adjustHeightSequenceDeleted(i); } - hiddenSequences.adjustHeightSequenceDeleted(i); } } @@ -1234,7 +1234,9 @@ public class Alignment implements AlignmentI return alignmentProperties; } - AlignedCodonFrame[] codonFrameList = null; + // AlignedCodonFrame[] codonFrameList = null; + + LinkedHashSet codonFrameList = new LinkedHashSet(); /* * (non-Javadoc) @@ -1246,31 +1248,10 @@ public class Alignment implements AlignmentI @Override public void addCodonFrame(AlignedCodonFrame codons) { - if (codons == null) - { - return; - } - if (codonFrameList == null) + if (codons != null) { - codonFrameList = new AlignedCodonFrame[] - { codons }; - return; + codonFrameList.add(codons); } - AlignedCodonFrame[] t = new AlignedCodonFrame[codonFrameList.length + 1]; - System.arraycopy(codonFrameList, 0, t, 0, codonFrameList.length); - t[codonFrameList.length] = codons; - codonFrameList = t; - } - - /* - * (non-Javadoc) - * - * @see jalview.datamodel.AlignmentI#getCodonFrame(int) - */ - @Override - public AlignedCodonFrame getCodonFrame(int index) - { - return codonFrameList[index]; } /* @@ -1280,27 +1261,21 @@ public class Alignment implements AlignmentI * jalview.datamodel.AlignmentI#getCodonFrame(jalview.datamodel.SequenceI) */ @Override - public AlignedCodonFrame[] getCodonFrame(SequenceI seq) + public List getCodonFrame(SequenceI seq) { - if (seq == null || codonFrameList == null) + if (seq == null) { return null; } - Vector cframes = new Vector(); - for (int f = 0; f < codonFrameList.length; f++) + List cframes = new ArrayList(); + for (AlignedCodonFrame acf : codonFrameList) { - if (codonFrameList[f].involvesSequence(seq)) + if (acf.involvesSequence(seq)) { - cframes.addElement(codonFrameList[f]); + cframes.add(acf); } } - if (cframes.size() == 0) - { - return null; - } - AlignedCodonFrame[] cfr = new AlignedCodonFrame[cframes.size()]; - cframes.copyInto(cfr); - return cfr; + return cframes; } /* @@ -1309,7 +1284,7 @@ public class Alignment implements AlignmentI * @see jalview.datamodel.AlignmentI#getCodonFrames() */ @Override - public AlignedCodonFrame[] getCodonFrames() + public Set getCodonFrames() { return codonFrameList; } @@ -1327,26 +1302,7 @@ public class Alignment implements AlignmentI { return false; } - boolean removed = false; - int i = 0, iSize = codonFrameList.length; - while (i < iSize) - { - if (codonFrameList[i] == codons) - { - removed = true; - if (i + 1 < iSize) - { - System.arraycopy(codonFrameList, i + 1, codonFrameList, i, iSize - - i - 1); - } - iSize--; - } - else - { - i++; - } - } - return removed; + return codonFrameList.remove(codons); } @Override @@ -1391,11 +1347,9 @@ public class Alignment implements AlignmentI { addAnnotation(alan[a]); } - AlignedCodonFrame[] acod = toappend.getCodonFrames(); - for (int a = 0; acod != null && a < acod.length; a++) - { - this.addCodonFrame(acod[a]); - } + + this.codonFrameList.addAll(toappend.getCodonFrames()); + List sg = toappend.getGroups(); if (sg != null) { diff --git a/src/jalview/datamodel/AlignmentI.java b/src/jalview/datamodel/AlignmentI.java index c526f2a..ac2596a 100755 --- a/src/jalview/datamodel/AlignmentI.java +++ b/src/jalview/datamodel/AlignmentI.java @@ -5,16 +5,16 @@ * This file is part of Jalview. * * Jalview is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License + * modify it under the terms of the GNU General License * as published by the Free Software Foundation, either version 3 * of the License, or (at your option) any later version. * * Jalview is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. + * PURPOSE. See the GNU General License for more details. * - * You should have received a copy of the GNU General Public License + * You should have received a copy of the GNU General License * along with Jalview. If not, see . * The Jalview Authors are detailed in the 'AUTHORS' file. */ @@ -35,7 +35,7 @@ public interface AlignmentI extends AnnotatedCollectionI * * @return Number of sequences in alignment */ - public int getHeight(); + int getHeight(); /** * @@ -44,7 +44,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @return Greatest sequence length within alignment. */ @Override - public int getWidth(); + int getWidth(); /** * Calculates if this set of sequences (visible and invisible) are all the @@ -52,7 +52,7 @@ public interface AlignmentI extends AnnotatedCollectionI * * @return true if all sequences in alignment are the same length */ - public boolean isAligned(); + boolean isAligned(); /** * Calculates if this set of sequences is all the same length @@ -61,7 +61,7 @@ public interface AlignmentI extends AnnotatedCollectionI * optionally exclude hidden sequences from test * @return true if all (or just visible) sequences are the same length */ - public boolean isAligned(boolean includeHidden); + boolean isAligned(boolean includeHidden); /** * Gets sequences as a Synchronized collection @@ -69,14 +69,14 @@ public interface AlignmentI extends AnnotatedCollectionI * @return All sequences in alignment. */ @Override - public List getSequences(); + List getSequences(); /** * Gets sequences as a SequenceI[] * * @return All sequences in alignment. */ - public SequenceI[] getSequencesArray(); + SequenceI[] getSequencesArray(); /** * Find a specific sequence in this alignment. @@ -86,14 +86,14 @@ public interface AlignmentI extends AnnotatedCollectionI * * @return SequenceI at given index. */ - public SequenceI getSequenceAt(int i); + SequenceI getSequenceAt(int i); /** * Returns a map of lists of sequences keyed by sequence name. * * @return */ - public Map> getSequencesByName(); + Map> getSequencesByName(); /** * Add a new sequence to this alignment. @@ -101,7 +101,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @param seq * New sequence will be added at end of alignment. */ - public void addSequence(SequenceI seq); + void addSequence(SequenceI seq); /** * Used to set a particular index of the alignment with the given sequence. @@ -111,7 +111,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @param seq * New sequence to be inserted. */ - public void setSequenceAt(int i, SequenceI seq); + void setSequenceAt(int i, SequenceI seq); /** * Deletes a sequence from the alignment @@ -119,7 +119,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @param s * Sequence to be deleted. */ - public void deleteSequence(SequenceI s); + void deleteSequence(SequenceI s); /** * Deletes a sequence from the alignment. @@ -127,7 +127,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @param i * Index of sequence to be deleted. */ - public void deleteSequence(int i); + void deleteSequence(int i); /** * Finds sequence in alignment using sequence name as query. @@ -137,9 +137,9 @@ public interface AlignmentI extends AnnotatedCollectionI * * @return Sequence matching query, if found. If not found returns null. */ - public SequenceI findName(String name); + SequenceI findName(String name); - public SequenceI[] findSequenceMatch(String name); + SequenceI[] findSequenceMatch(String name); /** * Finds index of a given sequence in the alignment. @@ -149,7 +149,7 @@ public interface AlignmentI extends AnnotatedCollectionI * * @return Index of sequence within the alignment or -1 if not found */ - public int findIndex(SequenceI s); + int findIndex(SequenceI s); /** * Finds group that given sequence is part of. @@ -160,7 +160,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @return First group found for sequence. WARNING : Sequences may be members * of several groups. This method is incomplete. */ - public SequenceGroup findGroup(SequenceI s); + SequenceGroup findGroup(SequenceI s); /** * Finds all groups that a given sequence is part of. @@ -170,7 +170,7 @@ public interface AlignmentI extends AnnotatedCollectionI * * @return All groups containing given sequence. */ - public SequenceGroup[] findAllGroups(SequenceI s); + SequenceGroup[] findAllGroups(SequenceI s); /** * Adds a new SequenceGroup to this alignment. @@ -178,7 +178,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @param sg * New group to be added. */ - public void addGroup(SequenceGroup sg); + void addGroup(SequenceGroup sg); /** * Deletes a specific SequenceGroup @@ -186,19 +186,19 @@ public interface AlignmentI extends AnnotatedCollectionI * @param g * Group will be deleted from alignment. */ - public void deleteGroup(SequenceGroup g); + void deleteGroup(SequenceGroup g); /** * Get all the groups associated with this alignment. * * @return All groups as a list. */ - public List getGroups(); + List getGroups(); /** * Deletes all groups from this alignment. */ - public void deleteAllGroups(); + void deleteAllGroups(); /** * Adds a new AlignmentAnnotation to this alignment @@ -206,7 +206,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @note Care should be taken to ensure that annotation is at least as wide as * the longest sequence in the alignment for rendering purposes. */ - public void addAnnotation(AlignmentAnnotation aa); + void addAnnotation(AlignmentAnnotation aa); /** * moves annotation to a specified index in alignment annotation display stack @@ -216,7 +216,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @param index * the destination position */ - public void setAnnotationIndex(AlignmentAnnotation aa, int index); + void setAnnotationIndex(AlignmentAnnotation aa, int index); /** * Deletes a specific AlignmentAnnotation from the alignment, and removes its @@ -228,7 +228,7 @@ public interface AlignmentI extends AnnotatedCollectionI * the annotation to delete * @return true if annotation was deleted from this alignment. */ - public boolean deleteAnnotation(AlignmentAnnotation aa); + boolean deleteAnnotation(AlignmentAnnotation aa); /** * Deletes a specific AlignmentAnnotation from the alignment, and optionally @@ -244,7 +244,7 @@ public interface AlignmentI extends AnnotatedCollectionI * into the alignment * @return true if annotation was deleted from this alignment. */ - public boolean deleteAnnotation(AlignmentAnnotation aa, boolean unhook); + boolean deleteAnnotation(AlignmentAnnotation aa, boolean unhook); /** * Get the annotation associated with this alignment (this can be null if no @@ -253,7 +253,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @return array of AlignmentAnnotation objects */ @Override - public AlignmentAnnotation[] getAlignmentAnnotation(); + AlignmentAnnotation[] getAlignmentAnnotation(); /** * Change the gap character used in this alignment to 'gc' @@ -261,34 +261,34 @@ public interface AlignmentI extends AnnotatedCollectionI * @param gc * the new gap character. */ - public void setGapCharacter(char gc); + void setGapCharacter(char gc); /** * Get the gap character used in this alignment * * @return gap character */ - public char getGapCharacter(); + char getGapCharacter(); /** * Test for all nucleotide alignment * * @return true if alignment is nucleotide sequence */ - public boolean isNucleotide(); + boolean isNucleotide(); /** * Test if alignment contains RNA structure * * @return true if RNA structure AligmnentAnnotation was added to alignment */ - public boolean hasRNAStructure(); + boolean hasRNAStructure(); /** * Set alignment to be a nucleotide sequence * */ - public void setNucleotide(boolean b); + void setNucleotide(boolean b); /** * Get the associated dataset for the alignment. @@ -296,7 +296,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @return Alignment containing dataset sequences or null of this is a * dataset. */ - public Alignment getDataset(); + Alignment getDataset(); /** * Set the associated dataset for the alignment, or create one. @@ -304,23 +304,23 @@ public interface AlignmentI extends AnnotatedCollectionI * @param dataset * The dataset alignment or null to construct one. */ - public void setDataset(Alignment dataset); + void setDataset(Alignment dataset); /** * pads sequences with gaps (to ensure the set looks like an alignment) * * @return boolean true if alignment was modified */ - public boolean padGaps(); + boolean padGaps(); - public HiddenSequences getHiddenSequences(); + HiddenSequences getHiddenSequences(); /** * Compact representation of alignment * * @return CigarArray */ - public CigarArray getCompactAlignment(); + CigarArray getCompactAlignment(); /** * Set an arbitrary key value pair for an alignment. Note: both key and value @@ -329,7 +329,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @param key * @param value */ - public void setProperty(Object key, Object value); + void setProperty(Object key, Object value); /** * Get a named property from the alignment. @@ -337,21 +337,21 @@ public interface AlignmentI extends AnnotatedCollectionI * @param key * @return value of property */ - public Object getProperty(Object key); + Object getProperty(Object key); /** * Get the property hashtable. * * @return hashtable of alignment properties (or null if none are defined) */ - public Hashtable getProperties(); + Hashtable getProperties(); /** * add a reference to a frame of aligned codons for this alignment * * @param codons */ - public void addCodonFrame(AlignedCodonFrame codons); + void addCodonFrame(AlignedCodonFrame codons); /** * remove a particular codon frame reference from this alignment @@ -359,27 +359,19 @@ public interface AlignmentI extends AnnotatedCollectionI * @param codons * @return true if codon frame was removed. */ - public boolean removeCodonFrame(AlignedCodonFrame codons); + boolean removeCodonFrame(AlignedCodonFrame codons); /** * get all codon frames associated with this alignment * * @return */ - public AlignedCodonFrame[] getCodonFrames(); - - /** - * get a particular codon frame - * - * @param index - * @return - */ - public AlignedCodonFrame getCodonFrame(int index); + Set getCodonFrames(); /** * get codon frames involving sequenceI */ - public AlignedCodonFrame[] getCodonFrame(SequenceI seq); + List getCodonFrame(SequenceI seq); /** * find sequence with given name in alignment @@ -391,7 +383,7 @@ public interface AlignmentI extends AnnotatedCollectionI * tried * @return matched sequence or null */ - public SequenceI findName(String token, boolean b); + SequenceI findName(String token, boolean b); /** * find next sequence with given name in alignment starting after a given @@ -407,7 +399,7 @@ public interface AlignmentI extends AnnotatedCollectionI * tried * @return matched sequence or null */ - public SequenceI findName(SequenceI startAfter, String token, boolean b); + SequenceI findName(SequenceI startAfter, String token, boolean b); /** * find first sequence in alignment which is involved in the given search @@ -416,7 +408,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @param results * @return -1 or index of sequence in alignment */ - public int findIndex(SearchResults results); + int findIndex(SearchResults results); /** * append sequences and annotation from another alignment object to this one. @@ -429,7 +421,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @param toappend * - the alignment to be appended. */ - public void append(AlignmentI toappend); + void append(AlignmentI toappend); /** * Justify the sequences to the left or right by deleting and inserting gaps @@ -439,7 +431,7 @@ public interface AlignmentI extends AnnotatedCollectionI * true if alignment padded to right, false to justify to left * @return true if alignment was changed TODO: return undo object */ - public boolean justify(boolean right); + boolean justify(boolean right); /** * add given annotation row at given position (0 is start, -1 is end) @@ -447,7 +439,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @param consensus * @param i */ - public void addAnnotation(AlignmentAnnotation consensus, int i); + void addAnnotation(AlignmentAnnotation consensus, int i); /** * search for or create a specific annotation row on the alignment @@ -467,7 +459,7 @@ public interface AlignmentI extends AnnotatedCollectionI * * @return existing annotation matching the given attributes */ - public AlignmentAnnotation findOrCreateAnnotation(String name, + AlignmentAnnotation findOrCreateAnnotation(String name, String calcId, boolean autoCalc, SequenceI seqRef, SequenceGroup groupRef); @@ -481,7 +473,7 @@ public interface AlignmentI extends AnnotatedCollectionI * @param up * @param i */ - public void moveSelectedSequencesByOne(SequenceGroup sg, + void moveSelectedSequencesByOne(SequenceGroup sg, Map map, boolean up); /** @@ -490,7 +482,7 @@ public interface AlignmentI extends AnnotatedCollectionI * * @param alignmentAnnotation */ - public void validateAnnotation(AlignmentAnnotation alignmentAnnotation); + void validateAnnotation(AlignmentAnnotation alignmentAnnotation); /** * Align this alignment the same as the given one. If both of the same type @@ -503,12 +495,12 @@ public interface AlignmentI extends AnnotatedCollectionI * @param al * @return */ - public int alignAs(AlignmentI al); + int alignAs(AlignmentI al); /** * Returns the set of distinct sequence names in the alignment. * * @return */ - public Set getSequenceNames(); + Set getSequenceNames(); } diff --git a/src/jalview/datamodel/CigarArray.java b/src/jalview/datamodel/CigarArray.java index 529891f..a55f676 100644 --- a/src/jalview/datamodel/CigarArray.java +++ b/src/jalview/datamodel/CigarArray.java @@ -20,7 +20,7 @@ */ package jalview.datamodel; -import java.util.Vector; +import java.util.List; public class CigarArray extends CigarBase { @@ -148,25 +148,25 @@ public class CigarArray extends CigarBase * internal constructor function - called by CigarArray(AlignmentI, ...); * * @param alignment - * @param columnSelection + * @param list * - vector of visible regions as returned from * columnSelection.getHiddenColumns() * @param selectionGroup */ private void constructFromAlignment(AlignmentI alignment, - Vector columnSelection, SequenceGroup selectionGroup) + List list, SequenceGroup selectionGroup) { int[] _startend = _calcStartEndBounds(alignment, selectionGroup); int start = _startend[1], end = _startend[2]; // now construct the CigarArray operations - if (columnSelection != null) + if (list != null) { int[] region; int hideStart, hideEnd; int last = start; - for (int j = 0; last < end & j < columnSelection.size(); j++) + for (int j = 0; last < end & j < list.size(); j++) { - region = (int[]) columnSelection.elementAt(j); + region = list.get(j); hideStart = region[0]; hideEnd = region[1]; // edit hidden regions to selection range diff --git a/src/jalview/datamodel/ColumnSelection.java b/src/jalview/datamodel/ColumnSelection.java index f414d13..a757feb 100644 --- a/src/jalview/datamodel/ColumnSelection.java +++ b/src/jalview/datamodel/ColumnSelection.java @@ -23,19 +23,24 @@ package jalview.datamodel; import jalview.util.ShiftList; import java.util.ArrayList; -import java.util.Enumeration; import java.util.List; -import java.util.Vector; /** * NOTE: Columns are zero based. */ public class ColumnSelection { - Vector selected = new Vector(); + /* + * Because autoboxing can convert int to Integer, have to be very careful + * using methods remove(int), remove(Integer) and set(int, Integer). + * Verification is in unit tests. + */ + List selected = new ArrayList(); - // Vector of int [] {startCol, endCol} - Vector hiddenColumns; + /* + * List of {startCol, endCol} hidden column ranges + */ + List hiddenColumns; /** * Add a column to the selection @@ -48,7 +53,7 @@ public class ColumnSelection Integer column = new Integer(col); if (!selected.contains(column)) { - selected.addElement(column); + selected.add(column); } } @@ -57,23 +62,18 @@ public class ColumnSelection */ public void clear() { - selected.removeAllElements(); + selected.clear(); } /** - * removes col from selection + * Removes column 'col' from selection (NOT the col'th item). * * @param col * index of column to be removed */ public void removeElement(int col) { - Integer colInt = new Integer(col); - - if (selected.contains(colInt)) - { - selected.removeElement(colInt); - } + selected.remove(new Integer(col)); } /** @@ -92,16 +92,16 @@ public class ColumnSelection colInt = new Integer(i); if (selected.contains(colInt)) { - selected.removeElement(colInt); + selected.remove(colInt); } } } /** * - * @return Vector containing selected columns as Integers + * @return list containing selected columns as Integers */ - public Vector getSelected() + public List getSelected() { return selected; } @@ -128,7 +128,8 @@ public class ColumnSelection */ public int columnAt(int i) { - return ((Integer) selected.elementAt(i)).intValue(); + // autoboxing Integer -> int + return selected.get(i); } /** @@ -168,7 +169,7 @@ public class ColumnSelection */ public int getMin() { - int min = 1000000000; + int min = Integer.MAX_VALUE; for (int i = 0; i < selected.size(); i++) { @@ -198,7 +199,8 @@ public class ColumnSelection if (temp >= start) { - selected.setElementAt(new Integer(temp - change), i); + // i = index here! + selected.set(i, new Integer(temp - change)); } } @@ -208,12 +210,12 @@ public class ColumnSelection int hSize = hiddenColumns.size(); for (int i = 0; i < hSize; i++) { - int[] region = (int[]) hiddenColumns.elementAt(i); + int[] region = hiddenColumns.get(i); if (region[0] > start && start + change > region[1]) { deletedHiddenColumns.add(region); - hiddenColumns.removeElementAt(i); + hiddenColumns.remove(i); i--; hSize--; continue; @@ -255,7 +257,8 @@ public class ColumnSelection if (temp >= start) { - selected.setElementAt(new Integer(temp - change), i); + // i is index position in list here! + selected.set(i, new Integer(temp - change)); } } @@ -263,7 +266,7 @@ public class ColumnSelection { for (int i = 0; i < hiddenColumns.size(); i++) { - int[] region = (int[]) hiddenColumns.elementAt(i); + int[] region = hiddenColumns.get(i); if (region[0] >= start) { region[0] -= change; @@ -274,7 +277,7 @@ public class ColumnSelection } if (region[1] < region[0]) { - hiddenColumns.removeElementAt(i--); + hiddenColumns.remove(i--); } if (region[0] < 0) @@ -300,13 +303,13 @@ public class ColumnSelection { if (shiftrecord != null) { - Vector shifts = shiftrecord.shifts; + List shifts = shiftrecord.getShifts(); if (shifts != null && shifts.size() > 0) { int shifted = 0; for (int i = 0, j = shifts.size(); i < j; i++) { - int[] sh = (int[]) shifts.elementAt(i); + int[] sh = shifts.get(i); // compensateForEdit(shifted+sh[0], sh[1]); compensateForDelEdits(shifted + sh[0], sh[1]); shifted -= sh[1]; @@ -321,16 +324,17 @@ public class ColumnSelection * removes intersection of position,length ranges in deletions from the * start,end regions marked in intervals. * - * @param deletions - * @param intervals + * @param shifts + * @param hiddenColumns2 * @return */ - private boolean pruneIntervalVector(Vector deletions, Vector intervals) + private boolean pruneIntervalVector(List shifts, + List hiddenColumns2) { boolean pruned = false; - int i = 0, j = intervals.size() - 1, s = 0, t = deletions.size() - 1; - int hr[] = (int[]) intervals.elementAt(i); - int sr[] = (int[]) deletions.elementAt(s); + int i = 0, j = hiddenColumns2.size() - 1, s = 0, t = shifts.size() - 1; + int hr[] = hiddenColumns2.get(i); + int sr[] = shifts.get(s); while (i <= j && s <= t) { boolean trailinghn = hr[1] >= sr[0]; @@ -338,7 +342,7 @@ public class ColumnSelection { if (i < j) { - hr = (int[]) intervals.elementAt(++i); + hr = hiddenColumns2.get(++i); } else { @@ -351,7 +355,7 @@ public class ColumnSelection { // leadinghc disjoint or not a deletion if (s < t) { - sr = (int[]) deletions.elementAt(++s); + sr = shifts.get(++s); } else { @@ -366,12 +370,12 @@ public class ColumnSelection { if (trailinghc) { // deleted hidden region. - intervals.removeElementAt(i); + hiddenColumns2.remove(i); pruned = true; j--; if (i <= j) { - hr = (int[]) intervals.elementAt(i); + hr = hiddenColumns2.remove(i); } continue; } @@ -397,7 +401,7 @@ public class ColumnSelection // sr contained in hr if (s < t) { - sr = (int[]) deletions.elementAt(++s); + sr = shifts.get(++s); } else { @@ -411,27 +415,28 @@ public class ColumnSelection // operations. } - private boolean pruneColumnList(Vector deletion, Vector list) + private boolean pruneColumnList(List shifts, List list) { - int s = 0, t = deletion.size(); - int[] sr = (int[]) list.elementAt(s++); + int s = 0, t = shifts.size(); + int[] sr = shifts.get(s++); boolean pruned = false; int i = 0, j = list.size(); while (i < j && s <= t) { - int c = ((Integer) list.elementAt(i++)).intValue(); + int c = list.get(i++); if (sr[0] <= c) { if (sr[1] + sr[0] >= c) - { // sr[1] -ve means inseriton. - list.removeElementAt(--i); + { // sr[1] -ve means insertion. + // remove the (i-1)'th element + list.remove(--i); j--; } else { if (s < t) { - sr = (int[]) deletion.elementAt(s); + sr = shifts.get(s); } s++; } @@ -450,7 +455,7 @@ public class ColumnSelection { if (deletions != null) { - Vector shifts = deletions.shifts; + List shifts = deletions.getShifts(); if (shifts != null && shifts.size() > 0) { // delete any intervals intersecting. @@ -477,14 +482,14 @@ public class ColumnSelection } /** - * This Method is used to return all the HiddenColumn regions less than the + * This method is used to return all the HiddenColumn regions less than the * given index. * * @param end * int * @return Vector */ - public Vector getHiddenColumns() + public List getHiddenColumns() { return hiddenColumns; } @@ -503,7 +508,7 @@ public class ColumnSelection { for (int i = 0; i < hiddenColumns.size(); i++) { - int[] region = (int[]) hiddenColumns.elementAt(i); + int[] region = hiddenColumns.get(i); if (result >= region[0]) { result += region[1] - region[0] + 1; @@ -531,7 +536,7 @@ public class ColumnSelection int[] region; do { - region = (int[]) hiddenColumns.elementAt(index++); + region = hiddenColumns.get(index++); if (hiddenColumn > region[1]) { result -= region[1] + 1 - region[0]; @@ -557,7 +562,7 @@ public class ColumnSelection int gaps = 0; do { - int[] region = (int[]) hiddenColumns.elementAt(index); + int[] region = hiddenColumns.get(index); if (hiddenRegion == 0) { return region[0]; @@ -588,7 +593,7 @@ public class ColumnSelection int index = 0; do { - int[] region = (int[]) hiddenColumns.elementAt(index); + int[] region = hiddenColumns.get(index); if (alPos < region[0]) { return region[0]; @@ -616,7 +621,7 @@ public class ColumnSelection int index = hiddenColumns.size() - 1; do { - int[] region = (int[]) hiddenColumns.elementAt(index); + int[] region = hiddenColumns.get(index); if (alPos > region[1]) { return region[1]; @@ -634,7 +639,7 @@ public class ColumnSelection { while (size() > 0) { - int column = ((Integer) getSelected().firstElement()).intValue(); + int column = getSelected().get(0).intValue(); hideColumns(column); } @@ -644,7 +649,7 @@ public class ColumnSelection { if (hiddenColumns == null) { - hiddenColumns = new Vector(); + hiddenColumns = new ArrayList(); } boolean added = false; @@ -652,17 +657,17 @@ public class ColumnSelection for (int i = 0; i < hiddenColumns.size(); i++) { - int[] region = (int[]) hiddenColumns.elementAt(i); + int[] region = hiddenColumns.get(i); if (start <= region[1] && end >= region[0]) { - hiddenColumns.removeElementAt(i); + hiddenColumns.remove(i); overlap = true; break; } else if (end < region[0] && start < region[0]) { - hiddenColumns.insertElementAt(new int[] - { start, end }, i); + hiddenColumns.add(i, new int[] + { start, end }); added = true; break; } @@ -674,7 +679,7 @@ public class ColumnSelection } else if (!added) { - hiddenColumns.addElement(new int[] + hiddenColumns.add(new int[] { start, end }); } @@ -719,7 +724,7 @@ public class ColumnSelection { for (int i = 0; i < hiddenColumns.size(); i++) { - int[] region = (int[]) hiddenColumns.elementAt(i); + int[] region = hiddenColumns.get(i); for (int j = region[0]; j < region[1] + 1; j++) { addElement(j); @@ -734,7 +739,7 @@ public class ColumnSelection { for (int i = 0; i < hiddenColumns.size(); i++) { - int[] region = (int[]) hiddenColumns.elementAt(i); + int[] region = hiddenColumns.get(i); if (res == region[0]) { for (int j = region[0]; j < region[1] + 1; j++) @@ -742,7 +747,7 @@ public class ColumnSelection addElement(j); } - hiddenColumns.removeElement(region); + hiddenColumns.remove(region); break; } } @@ -758,7 +763,7 @@ public class ColumnSelection { for (int i = 0; i < hiddenColumns.size(); i++) { - int[] region = (int[]) hiddenColumns.elementAt(i); + int[] region = hiddenColumns.get(i); if (column >= region[0] && column <= region[1]) { return false; @@ -780,24 +785,24 @@ public class ColumnSelection { if (copy.selected != null) { - selected = new Vector(); + selected = new ArrayList(); for (int i = 0, j = copy.selected.size(); i < j; i++) { - selected.addElement(copy.selected.elementAt(i)); + selected.add(copy.selected.get(i)); } } if (copy.hiddenColumns != null) { - hiddenColumns = new Vector(copy.hiddenColumns.size()); + hiddenColumns = new ArrayList(copy.hiddenColumns.size()); for (int i = 0, j = copy.hiddenColumns.size(); i < j; i++) { int[] rh, cp; - rh = (int[]) copy.hiddenColumns.elementAt(i); + rh = copy.hiddenColumns.get(i); if (rh != null) { cp = new int[rh.length]; System.arraycopy(rh, 0, cp, 0, rh.length); - hiddenColumns.addElement(cp); + hiddenColumns.add(cp); } } } @@ -821,15 +826,13 @@ public class ColumnSelection for (i = 0; i < iSize; i++) { StringBuffer visibleSeq = new StringBuffer(); - Vector regions = getHiddenColumns(); + List regions = getHiddenColumns(); int blockStart = start, blockEnd = end; - int[] region; int hideStart, hideEnd; - for (int j = 0; j < regions.size(); j++) + for (int[] region : regions) { - region = (int[]) regions.elementAt(j); hideStart = region[0]; hideEnd = region[1]; @@ -885,8 +888,8 @@ public class ColumnSelection { if (hiddenColumns != null && hiddenColumns.size() > 0) { - Vector visiblecontigs = new Vector(); - Vector regions = getHiddenColumns(); + List visiblecontigs = new ArrayList(); + List regions = getHiddenColumns(); int vstart = start; int[] region; @@ -894,7 +897,7 @@ public class ColumnSelection for (int j = 0; vstart < end && j < regions.size(); j++) { - region = (int[]) regions.elementAt(j); + region = regions.get(j); hideStart = region[0]; hideEnd = region[1]; @@ -904,7 +907,7 @@ public class ColumnSelection } if (hideStart > vstart) { - visiblecontigs.addElement(new int[] + visiblecontigs.add(new int[] { vstart, hideStart - 1 }); } vstart = hideEnd + 1; @@ -912,18 +915,18 @@ public class ColumnSelection if (vstart < end) { - visiblecontigs.addElement(new int[] + visiblecontigs.add(new int[] { vstart, end - 1 }); } int[] vcontigs = new int[visiblecontigs.size() * 2]; for (int i = 0, j = visiblecontigs.size(); i < j; i++) { - int[] vc = (int[]) visiblecontigs.elementAt(i); - visiblecontigs.setElementAt(null, i); + int[] vc = visiblecontigs.get(i); + visiblecontigs.set(i, null); vcontigs[i * 2] = vc[0]; vcontigs[i * 2 + 1] = vc[1]; } - visiblecontigs.removeAllElements(); + visiblecontigs.clear(); return vcontigs; } else @@ -970,16 +973,14 @@ public class ColumnSelection if (hiddenColumns != null && hiddenColumns.size() > 0) { // then mangle the alignmentAnnotation annotation array - Vector annels = new Vector(); + List annels = new ArrayList(); Annotation[] els = null; - Vector regions = getHiddenColumns(); + List regions = getHiddenColumns(); int blockStart = start, blockEnd = end; - int[] region; int hideStart, hideEnd, w = 0; - for (int j = 0; j < regions.size(); j++) + for (int[] region : regions) { - region = (int[]) regions.elementAt(j); hideStart = region[0]; hideEnd = region[1]; @@ -996,7 +997,7 @@ public class ColumnSelection break; } - annels.addElement(els = new Annotation[blockEnd - blockStart]); + annels.add(els = new Annotation[blockEnd - blockStart]); System.arraycopy(alignmentAnnotation.annotations, blockStart, els, 0, els.length); w += els.length; @@ -1006,7 +1007,7 @@ public class ColumnSelection if (end > blockStart) { - annels.addElement(els = new Annotation[end - blockStart + 1]); + annels.add(els = new Annotation[end - blockStart + 1]); if ((els.length + blockStart) <= alignmentAnnotation.annotations.length) { // copy just the visible segment of the annotation row @@ -1026,12 +1027,8 @@ public class ColumnSelection { return; } - Enumeration e = annels.elements(); - alignmentAnnotation.annotations = new Annotation[w]; - w = 0; - while (e.hasMoreElements()) + for (Annotation[] chnk : annels) { - Annotation[] chnk = (Annotation[]) e.nextElement(); System.arraycopy(chnk, 0, alignmentAnnotation.annotations, w, chnk.length); w += chnk.length; @@ -1079,15 +1076,13 @@ public class ColumnSelection { if (colsel != null && colsel.size() > 0) { - Enumeration e = colsel.getSelected().elements(); - while (e.hasMoreElements()) + for (Integer eo : colsel.getSelected()) { - Object eo = e.nextElement(); - if (hiddenColumns != null && isVisible(((Integer) eo).intValue())) + if (hiddenColumns != null && isVisible(eo)) { if (!selected.contains(eo)) { - selected.addElement(eo); + selected.add(eo); } } } @@ -1102,22 +1097,21 @@ public class ColumnSelection */ public void setElementsFrom(ColumnSelection colsel) { - selected = new Vector(); + selected = new ArrayList(); if (colsel.selected != null && colsel.selected.size() > 0) { if (hiddenColumns != null && hiddenColumns.size() > 0) { // only select visible columns in this columns selection - selected = new Vector(); + selected = new ArrayList(); addElementsFrom(colsel); } else { // add everything regardless - Enumeration en = colsel.selected.elements(); - while (en.hasMoreElements()) + for (Integer e : colsel.getSelected()) { - selected.addElement(en.nextElement()); + selected.add(e); } } } @@ -1177,7 +1171,7 @@ public class ColumnSelection { if (viscontigs[v] > spos) { - StringBuffer sb = new StringBuffer(); + StringBuilder sb = new StringBuilder(64); for (int s = 0, ns = viscontigs[v] - spos; s < ns; s++) { sb.append(gc); diff --git a/src/jalview/datamodel/SearchResults.java b/src/jalview/datamodel/SearchResults.java index d36c872..7a241fd 100755 --- a/src/jalview/datamodel/SearchResults.java +++ b/src/jalview/datamodel/SearchResults.java @@ -23,11 +23,49 @@ package jalview.datamodel; import java.util.ArrayList; import java.util.List; +/** + * Holds a list of search result matches, where each match is a contiguous + * stretch of a single sequence. + * + * @author gmcarstairs + * + */ public class SearchResults { private List matches = new ArrayList(); + public class Match + { + SequenceI sequence; + + int start; + + int end; + + public Match(SequenceI seq, int start, int end) + { + sequence = seq; + this.start = start; + this.end = end; + } + + public SequenceI getSequence() + { + return sequence; + } + + public int getStart() + { + return start; + } + + public int getEnd() + { + return end; + } + } + /** * This method replaces the old search results which merely held an alignment * index of search matches. This broke when sequences were moved around the @@ -149,30 +187,26 @@ public class SearchResults return matches.get(index).sequence; } - public int getResultStart(int index) - { - return matches.get(index).start; - } - - public int getResultEnd(int index) + /** + * Returns the start position of the i'th match in the search results. + * + * @param i + * @return + */ + public int getResultStart(int i) { - return matches.get(index).end; + return matches.get(i).start; } - class Match + /** + * Returns the end position of the i'th match in the search results. + * + * @param i + * @return + */ + public int getResultEnd(int i) { - SequenceI sequence; - - int start; - - int end; - - public Match(SequenceI seq, int start, int end) - { - sequence = seq; - this.start = start; - this.end = end; - } + return matches.get(i).end; } /** @@ -184,4 +218,14 @@ public class SearchResults { return matches.isEmpty(); } + + /** + * Returns the list of matches. + * + * @return + */ + public List getResults() + { + return matches; + } } diff --git a/src/jalview/datamodel/Sequence.java b/src/jalview/datamodel/Sequence.java index 6b0e9fc..7a31a7b 100755 --- a/src/jalview/datamodel/Sequence.java +++ b/src/jalview/datamodel/Sequence.java @@ -651,9 +651,7 @@ public class Sequence implements SequenceI */ public int[] gapMap() { - String seq = jalview.analysis.AlignSeq.extractGaps( - jalview.util.Comparison.GapChars, new String(sequence)); - int[] map = new int[seq.length()]; + int[] map = new int[sequence.length]; int j = 0; int p = 0; @@ -667,7 +665,9 @@ public class Sequence implements SequenceI j++; } - return map; + int[] compact = new int[p]; + System.arraycopy(map, 0, compact, 0, p); + return compact; } /* diff --git a/src/jalview/datamodel/SequenceI.java b/src/jalview/datamodel/SequenceI.java index 3ca759d..4b86756 100755 --- a/src/jalview/datamodel/SequenceI.java +++ b/src/jalview/datamodel/SequenceI.java @@ -172,8 +172,7 @@ public interface SequenceI public String getDescription(); /** - * Return the alignment column for a sequence position * Return the alignment - * position for a sequence position + * Return the alignment column for a sequence position * * @param pos * lying from start to end diff --git a/src/jalview/gui/AlignFrame.java b/src/jalview/gui/AlignFrame.java index b47e7d1..14a5de3 100644 --- a/src/jalview/gui/AlignFrame.java +++ b/src/jalview/gui/AlignFrame.java @@ -88,6 +88,7 @@ import jalview.schemes.UserColourScheme; import jalview.schemes.ZappoColourScheme; import jalview.structure.StructureSelectionManager; import jalview.util.MessageManager; +import jalview.viewmodel.AlignmentViewport; import jalview.ws.jws1.Discoverer; import jalview.ws.jws2.Jws2Discoverer; import jalview.ws.jws2.jabaws2.Jws2Instance; @@ -123,6 +124,7 @@ import java.util.Arrays; import java.util.Enumeration; import java.util.Hashtable; import java.util.List; +import java.util.Set; import java.util.Vector; import javax.swing.JButton; @@ -371,6 +373,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, reload.setEnabled(true); } + /** + * Add a KeyListener with handlers for various KeyPressed and KeyReleased + * events + */ void addKeyListener() { addKeyListener(new KeyAdapter() @@ -1585,7 +1591,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, // TODO: execute command before adding to redo list / broadcasting? command.undoCommand(getViewAlignments()); - AlignViewport originalSource = getOriginatingSource(command); + AlignmentViewport originalSource = getOriginatingSource(command); updateEditMenuBar(); if (originalSource != null) @@ -1624,7 +1630,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, viewport.addToHistoryList(command); command.doCommand(getViewAlignments()); - AlignViewport originalSource = getOriginatingSource(command); + AlignmentViewport originalSource = getOriginatingSource(command); updateEditMenuBar(); if (originalSource != null) @@ -1646,9 +1652,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } } - AlignViewport getOriginatingSource(CommandI command) + AlignmentViewport getOriginatingSource(CommandI command) { - AlignViewport originalSource = null; + AlignmentViewport originalSource = null; // For sequence removal and addition, we need to fire // the property change event FROM the viewport where the // original alignment was altered @@ -1706,25 +1712,22 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, viewport.getHiddenRepSequences(), up); alignPanel.paintAlignment(true); - final AlignViewportI slave = viewport.getSlave(); - if (slave != null) + final AlignViewportI peer = viewport.getCodingComplement(); + if (peer != null) { - final SequenceGroup selectionGroup = viewport.getSlave() - .getSelectionGroup(); + final SequenceGroup selectionGroup = peer.getSelectionGroup(); if (selectionGroup != null) { - viewport.getSlave() - .getAlignment() - .moveSelectedSequencesByOne( - viewport.getSlave().getSelectionGroup(), - viewport.getSlave().getHiddenRepSequences(), up); + peer.getAlignment().moveSelectedSequencesByOne( + peer.getSelectionGroup(), peer.getHiddenRepSequences(), up); + ((AlignViewport) peer).getAlignPanel().paintAlignment(true); } } } synchronized void slideSequences(boolean right, int size) { - List sg = new Vector(); + List sg = new ArrayList(); if (viewport.cursorMode) { sg.add(viewport.getAlignment().getSequenceAt( @@ -1743,13 +1746,13 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, return; } - Vector invertGroup = new Vector(); + List invertGroup = new ArrayList(); - for (int i = 0; i < viewport.getAlignment().getHeight(); i++) + for (SequenceI seq : viewport.getAlignment().getSequences()) { - if (!sg.contains(viewport.getAlignment().getSequenceAt(i))) + if (!sg.contains(seq)) { - invertGroup.add(viewport.getAlignment().getSequenceAt(i)); + invertGroup.add(seq); } } @@ -1758,7 +1761,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, SequenceI[] seqs2 = new SequenceI[invertGroup.size()]; for (int i = 0; i < invertGroup.size(); i++) { - seqs2[i] = (SequenceI) invertGroup.elementAt(i); + seqs2[i] = invertGroup.get(i); } SlideSequencesCommand ssc; @@ -1878,8 +1881,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, for (int i = 0; i < viewport.getColumnSelection().getHiddenColumns() .size(); i++) { - int[] region = (int[]) viewport.getColumnSelection() - .getHiddenColumns().elementAt(i); + int[] region = viewport.getColumnSelection() + .getHiddenColumns().get(i); if (region[0] >= hiddenOffset && region[1] <= hiddenCutoff) { hiddenColumns.addElement(new int[] @@ -1891,7 +1894,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, Desktop.jalviewClipboard = new Object[] { seqs, viewport.getAlignment().getDataset(), hiddenColumns }; statusBar.setText(MessageManager.formatMessage( - "label.copied_sequences_to_clipboard", new String[] + "label.copied_sequences_to_clipboard", new Object[] { Integer.valueOf(seqs.length).toString() })); } @@ -2684,16 +2687,6 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, .getSequences()); } - // else - { - // if (justifySeqs>0) - { - // alignment.justify(justifySeqs!=RIGHT_JUSTIFY); - } - } - - // } - /** * DOCUMENT ME! * @@ -4819,12 +4812,11 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, sprods[s].updatePDBIds(); } Alignment al = new Alignment(sprods); - AlignedCodonFrame[] cf = prods.getCodonFrames(); + Set cf = prods.getCodonFrames(); al.setDataset(ds); - for (int s = 0; cf != null && s < cf.length; s++) + for (AlignedCodonFrame acf : cf) { - al.addCodonFrame(cf[s]); - cf[s] = null; + al.addCodonFrame(acf); } AlignFrame naf = new AlignFrame(al, DEFAULT_WIDTH, DEFAULT_HEIGHT); @@ -5423,7 +5415,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, * * @param av */ - public boolean closeView(AlignViewport av) + public boolean closeView(AlignmentViewport av) { if (viewport == av) { @@ -5906,7 +5898,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, protected void viewAsCdna_actionPerformed() { final AlignmentI alignment = getViewport().getAlignment(); - AlignedCodonFrame[] mappings = alignment.getCodonFrames(); + Set mappings = alignment.getCodonFrames(); if (mappings == null) { return; diff --git a/src/jalview/gui/AlignViewport.java b/src/jalview/gui/AlignViewport.java index f00e4d3..5a9fa6b 100644 --- a/src/jalview/gui/AlignViewport.java +++ b/src/jalview/gui/AlignViewport.java @@ -1329,11 +1329,11 @@ public class AlignViewport extends AlignmentViewport implements StructureSelectionManager ssm, VamsasSource source) { /* - * ...work in progress... do nothing unless we are a 'slave' of the source - * May replace this with direct calls not via SSM. + * ...work in progress... do nothing unless we are a 'complement' of the + * source May replace this with direct calls not via SSM. */ if (source instanceof AlignViewportI - && ((AlignViewportI) source).getSlave() == this) + && ((AlignViewportI) source).getCodingComplement() == this) { // ok to continue; } @@ -1584,14 +1584,15 @@ public class AlignViewport extends AlignmentViewport implements AlignFrame.DEFAULT_HEIGHT); /* - * Set the cDNA to list for edits on the protein. + * Set the frames to list for each other's edit and sort commands. */ ssm.addCommandListener(cdnaFrame.getViewport()); + ssm.addCommandListener(proteinFrame.getViewport()); /* - * cDNA is 'slaved' to edits, selection, sorting, show/hide on protein + * cDNA view will mirror edits, selection, sorting, show/hide on protein */ - proteinFrame.getViewport().setSlave(cdnaFrame.getViewport()); + proteinFrame.getViewport().setCodingComplement(cdnaFrame.getViewport()); } return true; diff --git a/src/jalview/gui/AnnotationColourChooser.java b/src/jalview/gui/AnnotationColourChooser.java index b8996b6..018dc2b 100644 --- a/src/jalview/gui/AnnotationColourChooser.java +++ b/src/jalview/gui/AnnotationColourChooser.java @@ -27,6 +27,7 @@ import jalview.datamodel.SequenceGroup; import jalview.schemes.AnnotationColourGradient; import jalview.schemes.ColourSchemeI; import jalview.util.MessageManager; +import jalview.viewmodel.AlignmentViewport; import java.awt.BorderLayout; import java.awt.Color; @@ -58,7 +59,7 @@ public class AnnotationColourChooser extends JPanel { JInternalFrame frame; - AlignViewport av; + AlignmentViewport av; AlignmentPanel ap; @@ -76,7 +77,7 @@ public class AnnotationColourChooser extends JPanel */ boolean sliderDragging = false; - public AnnotationColourChooser(AlignViewport av, final AlignmentPanel ap) + public AnnotationColourChooser(AlignmentViewport av, final AlignmentPanel ap) { oldcs = av.getGlobalColourScheme(); if (av.getAlignment().getGroups() != null) diff --git a/src/jalview/gui/AnnotationLabels.java b/src/jalview/gui/AnnotationLabels.java index 6e8417f..bb762ff 100755 --- a/src/jalview/gui/AnnotationLabels.java +++ b/src/jalview/gui/AnnotationLabels.java @@ -878,8 +878,7 @@ public class AnnotationLabels extends JPanel implements MouseListener, hiddenColumns = new Vector(); for (int i = 0; i < av.getColumnSelection().getHiddenColumns().size(); i++) { - int[] region = (int[]) av.getColumnSelection().getHiddenColumns() - .elementAt(i); + int[] region = av.getColumnSelection().getHiddenColumns().get(i); hiddenColumns.addElement(new int[] { region[0], region[1] }); diff --git a/src/jalview/gui/CutAndPasteHtmlTransfer.java b/src/jalview/gui/CutAndPasteHtmlTransfer.java index 7fd091f..40a02f8 100644 --- a/src/jalview/gui/CutAndPasteHtmlTransfer.java +++ b/src/jalview/gui/CutAndPasteHtmlTransfer.java @@ -33,6 +33,7 @@ import javax.swing.event.HyperlinkEvent.EventType; import jalview.io.*; import jalview.jbgui.*; import jalview.util.MessageManager; +import jalview.viewmodel.AlignmentViewport; /** * Cut'n'paste files into the desktop See JAL-1105 @@ -43,7 +44,7 @@ import jalview.util.MessageManager; public class CutAndPasteHtmlTransfer extends GCutAndPasteHtmlTransfer { - AlignViewport viewport; + AlignmentViewport viewport; public CutAndPasteHtmlTransfer() { @@ -102,7 +103,7 @@ public class CutAndPasteHtmlTransfer extends GCutAndPasteHtmlTransfer /** * DOCUMENT ME! */ - public void setForInput(AlignViewport viewport) + public void setForInput(AlignmentViewport viewport) { this.viewport = viewport; if (viewport != null) diff --git a/src/jalview/gui/Desktop.java b/src/jalview/gui/Desktop.java index e2a57af..512c418 100644 --- a/src/jalview/gui/Desktop.java +++ b/src/jalview/gui/Desktop.java @@ -29,6 +29,7 @@ import jalview.io.JalviewFileView; import jalview.structure.StructureSelectionManager; import jalview.util.ImageMaker; import jalview.util.MessageManager; +import jalview.viewmodel.AlignmentViewport; import jalview.ws.params.ParamManager; import java.awt.BorderLayout; @@ -1363,7 +1364,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements return; } - AlignViewport source = null, target = null; + AlignmentViewport source = null, target = null; if (frames[0] instanceof AlignFrame) { source = ((AlignFrame) frames[0]).getCurrentView(); @@ -1628,7 +1629,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements public static int getViewCount(String alignmentId) { - AlignViewport[] aps = getViewports(alignmentId); + AlignmentViewport[] aps = getViewports(alignmentId); return (aps == null) ? 0 : aps.length; } @@ -1684,7 +1685,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements * unique alignment id * @return all viewports on the alignment bound to sequenceSetId */ - public static AlignViewport[] getViewports(String sequenceSetId) + public static AlignmentViewport[] getViewports(String sequenceSetId) { Vector viewp = new Vector(); if (desktop != null) @@ -1718,7 +1719,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements } if (viewp.size() > 0) { - AlignViewport[] vp = new AlignViewport[viewp.size()]; + AlignmentViewport[] vp = new AlignmentViewport[viewp.size()]; viewp.copyInto(vp); return vp; } @@ -2475,7 +2476,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements * @param av * @return alignFrame for av */ - public static AlignFrame getAlignFrameFor(AlignViewport av) + public static AlignFrame getAlignFrameFor(AlignmentViewport av) { if (desktop != null) { diff --git a/src/jalview/gui/FeatureSettings.java b/src/jalview/gui/FeatureSettings.java index 2210148..21bf6de 100644 --- a/src/jalview/gui/FeatureSettings.java +++ b/src/jalview/gui/FeatureSettings.java @@ -32,6 +32,7 @@ import jalview.io.JalviewFileChooser; import jalview.schemes.AnnotationColourGradient; import jalview.schemes.GraduatedColor; import jalview.util.MessageManager; +import jalview.viewmodel.AlignmentViewport; import jalview.ws.dbsources.das.api.jalviewSourceI; import java.awt.BorderLayout; @@ -1344,7 +1345,7 @@ public class FeatureSettings extends JPanel { SequenceI[] dataset, seqs; int iSize; - AlignViewport vp = af.getViewport(); + AlignmentViewport vp = af.getViewport(); if (vp.getSelectionGroup() != null && vp.getSelectionGroup().getSize() > 0) { diff --git a/src/jalview/gui/IdPanel.java b/src/jalview/gui/IdPanel.java index 6b1109a..e793c8c 100755 --- a/src/jalview/gui/IdPanel.java +++ b/src/jalview/gui/IdPanel.java @@ -363,6 +363,9 @@ public class IdPanel extends JPanel implements MouseListener, { selectSeq(seq); } + // TODO is this addition ok here? + av.isSelectionGroupChanged(true); + alignPanel.paintAlignment(true); } diff --git a/src/jalview/gui/Jalview2XML.java b/src/jalview/gui/Jalview2XML.java index 0e3d878..d3a7e2c 100644 --- a/src/jalview/gui/Jalview2XML.java +++ b/src/jalview/gui/Jalview2XML.java @@ -861,18 +861,18 @@ public class Jalview2XML jal = av.getAlignment(); } // SAVE MAPPINGS - if (jal.getCodonFrames() != null && jal.getCodonFrames().length > 0) + Set jac = jal.getCodonFrames(); + if (jac != null) { - jalview.datamodel.AlignedCodonFrame[] jac = jal.getCodonFrames(); - for (int i = 0; i < jac.length; i++) + for (AlignedCodonFrame acf : jac) { AlcodonFrame alc = new AlcodonFrame(); vamsasSet.addAlcodonFrame(alc); - if (jac[i].getProtMappings() != null - && jac[i].getProtMappings().length > 0) + if (acf.getProtMappings() != null + && acf.getProtMappings().length > 0) { - SequenceI[] dnas = jac[i].getdnaSeqs(); - jalview.datamodel.Mapping[] pmaps = jac[i].getProtMappings(); + SequenceI[] dnas = acf.getdnaSeqs(); + jalview.datamodel.Mapping[] pmaps = acf.getProtMappings(); for (int m = 0; m < pmaps.length; m++) { AlcodMap alcmap = new AlcodMap(); @@ -1239,8 +1239,8 @@ public class Jalview2XML for (int c = 0; c < av.getColumnSelection().getHiddenColumns() .size(); c++) { - int[] region = (int[]) av.getColumnSelection() - .getHiddenColumns().elementAt(c); + int[] region = av.getColumnSelection().getHiddenColumns() + .get(c); HiddenColumns hc = new HiddenColumns(); hc.setStart(region[0]); hc.setEnd(region[1]); diff --git a/src/jalview/gui/PCAPanel.java b/src/jalview/gui/PCAPanel.java index d2d6a98..412c25a 100644 --- a/src/jalview/gui/PCAPanel.java +++ b/src/jalview/gui/PCAPanel.java @@ -28,6 +28,7 @@ import jalview.datamodel.SequenceI; import jalview.jbgui.GPCAPanel; import jalview.schemes.ResidueProperties; import jalview.util.MessageManager; +import jalview.viewmodel.AlignmentViewport; import jalview.viewmodel.PCAModel; import java.awt.BorderLayout; @@ -67,7 +68,7 @@ public class PCAPanel extends GPCAPanel implements Runnable, AlignmentPanel ap; - AlignViewport av; + AlignmentViewport av; PCAModel pcaModel; diff --git a/src/jalview/gui/PairwiseAlignPanel.java b/src/jalview/gui/PairwiseAlignPanel.java index bc2c27c..29d6b71 100755 --- a/src/jalview/gui/PairwiseAlignPanel.java +++ b/src/jalview/gui/PairwiseAlignPanel.java @@ -26,6 +26,7 @@ import jalview.datamodel.Sequence; import jalview.datamodel.SequenceI; import jalview.jbgui.GPairwiseAlignPanel; import jalview.util.MessageManager; +import jalview.viewmodel.AlignmentViewport; import java.awt.event.ActionEvent; import java.util.Vector; @@ -39,7 +40,7 @@ import java.util.Vector; public class PairwiseAlignPanel extends GPairwiseAlignPanel { - AlignViewport av; + AlignmentViewport av; Vector sequences; @@ -49,7 +50,7 @@ public class PairwiseAlignPanel extends GPairwiseAlignPanel * @param av * DOCUMENT ME! */ - public PairwiseAlignPanel(AlignViewport av) + public PairwiseAlignPanel(AlignmentViewport av) { super(); this.av = av; diff --git a/src/jalview/gui/RotatableCanvas.java b/src/jalview/gui/RotatableCanvas.java index 1ff78b4..6aff578 100755 --- a/src/jalview/gui/RotatableCanvas.java +++ b/src/jalview/gui/RotatableCanvas.java @@ -30,6 +30,7 @@ import jalview.api.RotatableCanvasI; import jalview.datamodel.*; import jalview.math.*; import jalview.util.MessageManager; +import jalview.viewmodel.AlignmentViewport; /** * DOCUMENT ME! @@ -101,7 +102,7 @@ public class RotatableCanvas extends JPanel implements MouseListener, float scalefactor = 1; - AlignViewport av; + AlignmentViewport av; AlignmentPanel ap; diff --git a/src/jalview/gui/ScalePanel.java b/src/jalview/gui/ScalePanel.java index f2c5154..4b3f656 100755 --- a/src/jalview/gui/ScalePanel.java +++ b/src/jalview/gui/ScalePanel.java @@ -20,14 +20,28 @@ */ package jalview.gui; -import java.awt.*; -import java.awt.event.*; - -import javax.swing.*; - -import jalview.datamodel.*; +import jalview.datamodel.ColumnSelection; +import jalview.datamodel.SequenceGroup; +import jalview.datamodel.SequenceI; import jalview.util.MessageManager; +import java.awt.Color; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; + +import javax.swing.JMenuItem; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.SwingUtilities; +import javax.swing.ToolTipManager; + /** * DOCUMENT ME! * @@ -357,8 +371,7 @@ public class ScalePanel extends JPanel implements MouseMotionListener, reveal = null; for (int i = 0; i < av.getColumnSelection().getHiddenColumns().size(); i++) { - int[] region = (int[]) av.getColumnSelection().getHiddenColumns() - .elementAt(i); + int[] region = av.getColumnSelection().getHiddenColumns().get(i); if (res + 1 == region[0] || res - 1 == region[1]) { reveal = region; @@ -466,18 +479,18 @@ public class ScalePanel extends JPanel implements MouseMotionListener, } gg.drawLine( - (int) (((i - startx - 1) * av.charWidth) + (av.charWidth / 2)), + ((i - startx - 1) * av.charWidth) + (av.charWidth / 2), y + 2, - (int) (((i - startx - 1) * av.charWidth) + (av.charWidth / 2)), + ((i - startx - 1) * av.charWidth) + (av.charWidth / 2), y + (fm.getDescent() * 2)); } else { gg.drawLine( - (int) (((i - startx - 1) * av.charWidth) + (av.charWidth / 2)), + ((i - startx - 1) * av.charWidth) + (av.charWidth / 2), y + fm.getDescent(), - (int) (((i - startx - 1) * av.charWidth) + (av.charWidth / 2)), + ((i - startx - 1) * av.charWidth) + (av.charWidth / 2), y + (fm.getDescent() * 2)); } } diff --git a/src/jalview/gui/SeqCanvas.java b/src/jalview/gui/SeqCanvas.java index d73ee70..a21d72a 100755 --- a/src/jalview/gui/SeqCanvas.java +++ b/src/jalview/gui/SeqCanvas.java @@ -34,6 +34,7 @@ import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.image.BufferedImage; +import java.util.List; import javax.swing.JComponent; @@ -636,15 +637,14 @@ public class SeqCanvas extends JComponent } else { - java.util.Vector regions = av.getColumnSelection().getHiddenColumns(); + List regions = av.getColumnSelection().getHiddenColumns(); int screenY = 0; int blockStart = startRes; int blockEnd = endRes; - for (int i = 0; regions != null && i < regions.size(); i++) + for (int[] region : regions) { - int[] region = (int[]) regions.elementAt(i); int hideStart = region[0]; int hideEnd = region[1]; diff --git a/src/jalview/gui/SeqPanel.java b/src/jalview/gui/SeqPanel.java index cca1685..891aa0d 100644 --- a/src/jalview/gui/SeqPanel.java +++ b/src/jalview/gui/SeqPanel.java @@ -24,7 +24,6 @@ import jalview.api.AlignViewportI; import jalview.commands.EditCommand; import jalview.commands.EditCommand.Action; import jalview.commands.EditCommand.Edit; -import jalview.datamodel.AlignedCodonFrame; import jalview.datamodel.ColumnSelection; import jalview.datamodel.SearchResults; import jalview.datamodel.Sequence; @@ -39,7 +38,9 @@ import jalview.structure.SequenceListener; import jalview.structure.StructureSelectionManager; import jalview.structure.VamsasSource; import jalview.util.Comparison; +import jalview.util.MappingUtils; import jalview.util.MessageManager; +import jalview.viewmodel.AlignmentViewport; import java.awt.BorderLayout; import java.awt.Color; @@ -1872,7 +1873,7 @@ public class SeqPanel extends JPanel implements MouseListener, // TODO: extend config options to allow user to control if selections may be // shared between viewports. boolean iSentTheSelection = (av == source - || (source instanceof AlignViewport && ((AlignViewport) source) + || (source instanceof AlignViewport && ((AlignmentViewport) source) .getSequenceSetId().equals(av.getSequenceSetId()))); if (iSentTheSelection || !av.followSelection) { @@ -1888,9 +1889,10 @@ public class SeqPanel extends JPanel implements MouseListener, } /* - * Check for selection in a view of which this one is a 'slave'. + * Check for selection in a view of which this one is a dna/protein + * complement. */ - if (selectionAsSlave(seqsel, colsel, source)) + if (selectionFromTranslation(seqsel, colsel, source)) { return; } @@ -1976,62 +1978,41 @@ public class SeqPanel extends JPanel implements MouseListener, } /** - * If this panel is a 'slave' of the selection source, tries to map the source - * selection to a local one, and returns true. Else returns false. + * If this panel is a cdna/protein translation view of the selection source, + * tries to map the source selection to a local one, and returns true. Else + * returns false. * * @param seqsel * @param colsel * @param source */ - protected boolean selectionAsSlave(SequenceGroup seqsel, + protected boolean selectionFromTranslation(SequenceGroup seqsel, ColumnSelection colsel, SelectionSource source) { if (!(source instanceof AlignViewportI)) { return false; } final AlignViewportI sourceAv = (AlignViewportI) source; - if (sourceAv.getSlave() != av) + if (sourceAv.getCodingComplement() != av && av.getCodingComplement() != sourceAv) { return false; } /* - * Map sequence selection. Note the SequenceGroup holds aligned sequences, - * the mappings hold dataset sequences. + * Map sequence selection */ - AlignedCodonFrame[] codonFrames = sourceAv.getAlignment() - .getCodonFrames(); - SequenceGroup sg = new SequenceGroup(); - for (SequenceI selected : seqsel.getSequences()) - { - for (AlignedCodonFrame acf : codonFrames) - { - SequenceI dnaSeq = acf.getDnaForAaSeq(selected); - if (dnaSeq != null) - { - for (SequenceI seq : av.getAlignment().getSequences()) - { - if (seq.getDatasetSequence() == dnaSeq) - { - sg.addSequence(seq, false); - break; - } - } - } - } - } + SequenceGroup sg = MappingUtils.mapSequenceGroup(seqsel, sourceAv, av); av.setSelectionGroup(sg); av.isSelectionGroupChanged(true); - // ((AlignmentViewport) slave).firePropertyChange("alignment", null, slave - // .getAlignment() - // .getSequences()); /* * Map column selection */ - // TODO + ColumnSelection cs = MappingUtils.mapColumnSelection(colsel, sourceAv, + av); + av.setColumnSelection(cs); + av.isColSelChanged(true); - AlignmentPanel ap = av.getAlignPanel(); PaintRefresher.Refresh(this, av.getSequenceSetId()); return true; diff --git a/src/jalview/gui/SplitFrame.java b/src/jalview/gui/SplitFrame.java index a28c0cf..2288d72 100644 --- a/src/jalview/gui/SplitFrame.java +++ b/src/jalview/gui/SplitFrame.java @@ -2,7 +2,21 @@ package jalview.gui; import jalview.jbgui.GSplitFrame; +import java.awt.Component; +import java.awt.MouseInfo; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.util.Map.Entry; + +import javax.swing.AbstractAction; import javax.swing.JComponent; +import javax.swing.JMenuItem; +import javax.swing.KeyStroke; import javax.swing.event.InternalFrameAdapter; import javax.swing.event.InternalFrameEvent; @@ -21,11 +35,21 @@ public class SplitFrame extends GSplitFrame */ protected void init() { - setSize(AlignFrame.DEFAULT_WIDTH, Desktop.instance.getHeight() - 10); + setSize(AlignFrame.DEFAULT_WIDTH, Desktop.instance.getHeight() - 20); - /* - * Add a listener to tidy up when the frame is closed. - */ + addCloseFrameListener(); + + addKeyListener(); + + addKeyBindings(); + + } + + /** + * Add a listener to tidy up when the frame is closed. + */ + protected void addCloseFrameListener() + { addInternalFrameListener(new InternalFrameAdapter() { @Override @@ -43,7 +67,121 @@ public class SplitFrame extends GSplitFrame } }; }); + } + + /** + * Add a key listener that delegates to whichever split component the mouse is + * in (or does nothing if neither). + */ + protected void addKeyListener() + { + // TODO Key Bindings rather than KeyListener are recommended for Swing + addKeyListener(new KeyAdapter() { + + @Override + public void keyPressed(KeyEvent e) + { + Component c = getComponentAtMouse(); + if (c != null) + { + for (KeyListener kl : c.getKeyListeners()) + { + kl.keyPressed(e); + } + } + } + + @Override + public void keyReleased(KeyEvent e) + { + Component c = getComponentAtMouse(); + if (c != null) + { + for (KeyListener kl : c.getKeyListeners()) + { + kl.keyReleased(e); + } + } + } + + }); + } + /** + * Returns the split pane component the mouse is in, or null if neither. + * + * @return + */ + protected Component getComponentAtMouse() + { + Point loc = MouseInfo.getPointerInfo().getLocation(); + + if (isIn(loc, getTopComponent())) { + return getTopComponent(); + } + else if (isIn(loc, getBottomComponent())) + { + return getBottomComponent(); + } + return null; } + private boolean isIn(Point loc, JComponent comp) + { + Point p = comp.getLocationOnScreen(); + Rectangle r = new Rectangle(p.x, p.y, comp.getWidth(), comp.getHeight()); + return r.contains(loc); + } + + /** + * Set key bindings (recommended for Swing over key accelerators). + */ + private void addKeyBindings() + { + /* + * Bind Cmd-Alt/I (invert column selection) + */ + // If AlignFrame exposed a Map of Action objects by key, + // we could delegate all key bindings with a single lookup + this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put( + KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_I, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask() + | java.awt.event.KeyEvent.ALT_MASK, false), + "INV_SEQ_SEL"); + this.getActionMap().put("INV_SEQ_SEL", new AbstractAction() + { + @Override + public void actionPerformed(ActionEvent e) + { + Component c = getComponentAtMouse(); + if (c instanceof AlignFrame) + { + ((AlignFrame) c).invertColSel_actionPerformed(null); + } + } + }); + if (getTopComponent() instanceof AlignFrame) + { + for (Entry acc : ((AlignFrame) getTopComponent()) + .getAccelerators().entrySet()) + { + + final KeyStroke ks = acc.getKey(); + this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(ks, ks); + this.getActionMap().put(ks, new AbstractAction() + { + @Override + public void actionPerformed(ActionEvent e) + { + Component c = getComponentAtMouse(); + if (c instanceof AlignFrame) + { + ((AlignFrame) c).getAccelerators().get(ks) + .getActionListeners()[0].actionPerformed(null); + } + } + }); + } + } + } } diff --git a/src/jalview/gui/TreeCanvas.java b/src/jalview/gui/TreeCanvas.java index e700fb3..e90f867 100755 --- a/src/jalview/gui/TreeCanvas.java +++ b/src/jalview/gui/TreeCanvas.java @@ -22,6 +22,7 @@ package jalview.gui; import jalview.analysis.Conservation; import jalview.analysis.NJTree; +import jalview.api.AlignViewportI; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; @@ -892,11 +893,11 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable, aps[a].av.getAlignment().deleteAllGroups(); aps[a].av.clearSequenceColours(); } - if (av.getSlave() != null) + if (av.getCodingComplement() != null) { - av.getSlave().setSelectionGroup(null); - av.getSlave().getAlignment().deleteAllGroups(); - av.getSlave().clearSequenceColours(); + av.getCodingComplement().setSelectionGroup(null); + av.getCodingComplement().getAlignment().deleteAllGroups(); + av.getCodingComplement().clearSequenceColours(); } colourGroups(); } @@ -981,21 +982,21 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable, // TODO can we push all of the below into AlignViewportI? av.getAlignment().addGroup(sg); - if (av.getSlave() != null) + final AlignViewportI codingComplement = av.getCodingComplement(); + if (codingComplement != null) { SequenceGroup mappedGroup = MappingUtils.mapSequenceGroup(sg, av, - av.getSlave()); + codingComplement); if (mappedGroup.getSequences().size() > 0) { - av.getSlave().getAlignment().addGroup(mappedGroup); + codingComplement.getAlignment().addGroup(mappedGroup); for (SequenceI seq : mappedGroup.getSequences()) { - av.getSlave().setSequenceColour(seq, + codingComplement.setSequenceColour(seq, mappedGroup.getIdColour().brighter()); } } } - } // notify the panel to redo any group specific stuff. @@ -1006,9 +1007,9 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable, // to any Jmols listening in } - if (av.getSlave() != null) + if (av.getCodingComplement() != null) { - ((AlignViewport) av.getSlave()).getAlignPanel().updateAnnotation(); + ((AlignViewport) av.getCodingComplement()).getAlignPanel().updateAnnotation(); /* * idPanel. repaint () */ diff --git a/src/jalview/gui/TreePanel.java b/src/jalview/gui/TreePanel.java index ce28d39..0c5ff32 100755 --- a/src/jalview/gui/TreePanel.java +++ b/src/jalview/gui/TreePanel.java @@ -39,6 +39,7 @@ import jalview.io.JalviewFileView; import jalview.io.NewickFile; import jalview.jbgui.GTreePanel; import jalview.util.MessageManager; +import jalview.viewmodel.AlignmentViewport; import java.awt.Font; import java.awt.Graphics; @@ -134,7 +135,7 @@ public class TreePanel extends GTreePanel return treeCanvas.av.getAlignment(); } - public AlignViewport getViewPort() + public AlignmentViewport getViewPort() { return treeCanvas.av; } @@ -597,7 +598,7 @@ public class TreePanel extends GTreePanel public CommandI sortAlignmentIn(AlignmentPanel ap) { - AlignViewport av = ap.av; + AlignmentViewport av = ap.av; SequenceI[] oldOrder = av.getAlignment().getSequencesArray(); AlignmentSorter.sortByTree(av.getAlignment(), tree); CommandI undo; diff --git a/src/jalview/gui/VamsasApplication.java b/src/jalview/gui/VamsasApplication.java index 56feef5..a9fa009 100644 --- a/src/jalview/gui/VamsasApplication.java +++ b/src/jalview/gui/VamsasApplication.java @@ -32,12 +32,12 @@ import jalview.structure.StructureSelectionManager; import jalview.structure.VamsasListener; import jalview.structure.VamsasSource; import jalview.util.MessageManager; +import jalview.viewmodel.AlignmentViewport; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.io.IOException; -import java.util.Enumeration; import java.util.Hashtable; import java.util.IdentityHashMap; import java.util.Iterator; @@ -1003,7 +1003,7 @@ public class VamsasApplication implements SelectionSource, VamsasSource AlignmentI visal = null; if (source instanceof AlignViewport) { - visal = ((AlignViewport) source).getAlignment(); + visal = ((AlignmentViewport) source).getAlignment(); } SelectionMessage sm = null; if ((seqsel == null || seqsel.getSize() == 0) @@ -1014,7 +1014,7 @@ public class VamsasApplication implements SelectionSource, VamsasSource { // the empty selection. sm = new SelectionMessage("jalview", new String[] - { ((AlignViewport) source).getSequenceSetId() }, null, + { ((AlignmentViewport) source).getSequenceSetId() }, null, true); } else @@ -1055,10 +1055,8 @@ public class VamsasApplication implements SelectionSource, VamsasSource { // gather selected columns outwith the sequence positions // too - Enumeration cols = colsel.getSelected().elements(); - while (cols.hasMoreElements()) + for (int ival : colsel.getSelected()) { - int ival = ((Integer) cols.nextElement()).intValue(); Pos p = new Pos(); p.setI(ival + 1); range.addPos(p); diff --git a/src/jalview/io/VamsasAppDatastore.java b/src/jalview/io/VamsasAppDatastore.java index ae3093c..63da089 100644 --- a/src/jalview/io/VamsasAppDatastore.java +++ b/src/jalview/io/VamsasAppDatastore.java @@ -34,6 +34,7 @@ import jalview.io.vamsas.DatastoreItem; import jalview.io.vamsas.DatastoreRegistry; import jalview.io.vamsas.Rangetype; import jalview.util.MessageManager; +import jalview.viewmodel.AlignmentViewport; import java.io.IOException; import java.util.Enumeration; @@ -42,12 +43,35 @@ import java.util.Hashtable; import java.util.IdentityHashMap; import java.util.Iterator; import java.util.List; +import java.util.Set; import java.util.Vector; import java.util.jar.JarInputStream; import java.util.jar.JarOutputStream; -import uk.ac.vamsas.client.*; -import uk.ac.vamsas.objects.core.*; +import uk.ac.vamsas.client.IClientAppdata; +import uk.ac.vamsas.client.IClientDocument; +import uk.ac.vamsas.client.Vobject; +import uk.ac.vamsas.client.VorbaId; +import uk.ac.vamsas.objects.core.Alignment; +import uk.ac.vamsas.objects.core.AlignmentSequence; +import uk.ac.vamsas.objects.core.AlignmentSequenceAnnotation; +import uk.ac.vamsas.objects.core.AnnotationElement; +import uk.ac.vamsas.objects.core.DataSet; +import uk.ac.vamsas.objects.core.DataSetAnnotations; +import uk.ac.vamsas.objects.core.DbRef; +import uk.ac.vamsas.objects.core.Entry; +import uk.ac.vamsas.objects.core.Glyph; +import uk.ac.vamsas.objects.core.Local; +import uk.ac.vamsas.objects.core.MapType; +import uk.ac.vamsas.objects.core.Mapped; +import uk.ac.vamsas.objects.core.Property; +import uk.ac.vamsas.objects.core.Provenance; +import uk.ac.vamsas.objects.core.RangeAnnotation; +import uk.ac.vamsas.objects.core.RangeType; +import uk.ac.vamsas.objects.core.Seg; +import uk.ac.vamsas.objects.core.Sequence; +import uk.ac.vamsas.objects.core.SequenceType; +import uk.ac.vamsas.objects.core.VAMSAS; import uk.ac.vamsas.objects.utils.Properties; /* @@ -728,12 +752,12 @@ public class VamsasAppDatastore * @return true if alignment associated with this view will be stored in * document. */ - public boolean alignmentWillBeSkipped(AlignViewport av) + public boolean alignmentWillBeSkipped(AlignmentViewport av) { return (!av.getAlignment().isAligned()); } - private void addToSkipList(AlignViewport av) + private void addToSkipList(AlignmentViewport av) { if (skipList == null) { @@ -1068,8 +1092,10 @@ public class VamsasAppDatastore an.addProperty(Properties.newProperty(THRESHOLD, Properties.FLOATTYPE, "" + alan.getThreshold().value)); if (alan.getThreshold().label != null) + { an.addProperty(Properties.newProperty(THRESHOLD + "Name", Properties.STRINGTYPE, "" + alan.getThreshold().label)); + } } ((DataSet) sref.getV_parent()).addDataSetAnnotations(an); bindjvvobj(alan, an); @@ -1381,12 +1407,12 @@ public class VamsasAppDatastore // sync, // and if any contain more than one view, then remove the one generated by // document update. - AlignViewport views[], av = null; + AlignmentViewport views[], av = null; AlignFrame af = null; Iterator newviews = newAlignmentViews.iterator(); while (newviews.hasNext()) { - av = (AlignViewport) newviews.next(); + av = (AlignmentViewport) newviews.next(); af = Desktop.getAlignFrameFor(av); // TODO implement this : af.getNumberOfViews String seqsetidobj = av.getSequenceSetId(); @@ -1403,7 +1429,8 @@ public class VamsasAppDatastore // to the align frames. boolean gathered = false; String newviewid = null; - AlignedCodonFrame[] mappings = av.getAlignment().getCodonFrames(); + Set mappings = av.getAlignment() + .getCodonFrames(); for (int i = 0; i < views.length; i++) { if (views[i] != av) @@ -1438,7 +1465,7 @@ public class VamsasAppDatastore { // ensure sequence mappings from vamsas document view still // active - if (mappings != null && mappings.length > 0) + if (mappings != null) { jalview.structure.StructureSelectionManager .getStructureSelectionManager(Desktop.instance) @@ -1682,7 +1709,7 @@ public class VamsasAppDatastore uk.ac.vamsas.objects.core.Alignment alignment = dataset .getAlignment(al); // TODO check this handles multiple views properly - AlignViewport av = findViewport(alignment); + AlignmentViewport av = findViewport(alignment); jalview.datamodel.AlignmentI jal = null; if (av != null) @@ -1956,10 +1983,10 @@ public class VamsasAppDatastore return newAlignmentViews.size(); } - public AlignViewport findViewport(Alignment alignment) + public AlignmentViewport findViewport(Alignment alignment) { - AlignViewport av = null; - AlignViewport[] avs = Desktop + AlignmentViewport av = null; + AlignmentViewport[] avs = Desktop .getViewports((String) getvObj2jv(alignment)); if (avs != null) { @@ -2207,6 +2234,7 @@ public class VamsasAppDatastore Cache.log.warn("Failed to parse threshold property"); } if (val != null) + { if (gl == null) { gl = new GraphLine(val.floatValue(), "", java.awt.Color.black); @@ -2215,11 +2243,14 @@ public class VamsasAppDatastore { gl.value = val.floatValue(); } + } } else if (props[p].getName().equalsIgnoreCase(THRESHOLD + "Name")) { if (gl == null) + { gl = new GraphLine(0, "", java.awt.Color.black); + } gl.label = props[p].getContent(); } } @@ -2670,10 +2701,10 @@ public class VamsasAppDatastore return vobj2jv; } - public void storeSequenceMappings(AlignViewport viewport, String title) + public void storeSequenceMappings(AlignmentViewport viewport, String title) throws Exception { - AlignViewport av = viewport; + AlignmentViewport av = viewport; try { jalview.datamodel.AlignmentI jal = av.getAlignment(); @@ -2695,18 +2726,15 @@ public class VamsasAppDatastore } // Store any sequence mappings. - if (av.getAlignment().getCodonFrames() != null - && av.getAlignment().getCodonFrames().length > 0) + Set cframes = av.getAlignment().getCodonFrames(); + if (cframes != null) { - jalview.datamodel.AlignedCodonFrame[] cframes = av.getAlignment() - .getCodonFrames(); - for (int cf = 0; cf < cframes.length; cf++) + for (AlignedCodonFrame acf : cframes) { - if (cframes[cf].getdnaSeqs() != null - && cframes[cf].getdnaSeqs().length > 0) + if (acf.getdnaSeqs() != null && acf.getdnaSeqs().length > 0) { - jalview.datamodel.SequenceI[] dmps = cframes[cf].getdnaSeqs(); - jalview.datamodel.Mapping[] mps = cframes[cf].getProtMappings(); + jalview.datamodel.SequenceI[] dmps = acf.getdnaSeqs(); + jalview.datamodel.Mapping[] mps = acf.getProtMappings(); for (int smp = 0; smp < mps.length; smp++) { uk.ac.vamsas.objects.core.SequenceType mfrom = (SequenceType) getjv2vObj(dmps[smp]); diff --git a/src/jalview/io/vamsas/Sequencemapping.java b/src/jalview/io/vamsas/Sequencemapping.java index 6fa49a0..3e20dcd 100644 --- a/src/jalview/io/vamsas/Sequencemapping.java +++ b/src/jalview/io/vamsas/Sequencemapping.java @@ -21,6 +21,7 @@ package jalview.io.vamsas; import jalview.datamodel.AlignedCodonFrame; +import jalview.datamodel.AlignmentI; import jalview.datamodel.Mapping; import jalview.datamodel.SequenceI; import jalview.gui.Desktop; @@ -325,19 +326,17 @@ public class Sequencemapping extends Rangetype } // create mapping storage object and make each dataset alignment reference // it. - jalview.datamodel.AlignmentI dsLoc = (jalview.datamodel.AlignmentI) getvObj2jv(sdloc - .getV_parent()); - jalview.datamodel.AlignmentI dsMap = (jalview.datamodel.AlignmentI) getvObj2jv(sdmap - .getV_parent()); - AlignedCodonFrame afc = new AlignedCodonFrame(); + AlignmentI dsLoc = (AlignmentI) getvObj2jv(sdloc.getV_parent()); + AlignmentI dsMap = (AlignmentI) getvObj2jv(sdmap.getV_parent()); + AlignedCodonFrame acf = new AlignedCodonFrame(); if (dsLoc != null && dsLoc != dsMap) { - dsLoc.addCodonFrame(afc); + dsLoc.addCodonFrame(acf); } if (dsMap != null) { - dsMap.addCodonFrame(afc); + dsMap.addCodonFrame(acf); } // create and add the new mapping to (each) dataset's codonFrame @@ -350,24 +349,22 @@ public class Sequencemapping extends Rangetype mapping = new jalview.util.MapList(mapping.getToRanges(), mapping.getFromRanges(), mapping.getToRatio(), mapping.getFromRatio()); - afc.addMap(to, from, mapping); + acf.addMap(to, from, mapping); } else { mapping = this.parsemapType(sequenceMapping, 3, 1); // correct sense - afc.addMap(from, to, mapping); + acf.addMap(from, to, mapping); } } else { mapping = this.parsemapType(sequenceMapping, 1, 1); // correct sense - afc.addMap(from, to, mapping); + acf.addMap(from, to, mapping); } bindjvvobj(mapping, sequenceMapping); jalview.structure.StructureSelectionManager - .getStructureSelectionManager(Desktop.instance).addMappings( - new AlignedCodonFrame[] - { afc }); + .getStructureSelectionManager(Desktop.instance).addMapping(acf); // Try to link up any conjugate database references in the two sequences // matchConjugateDBRefs(from, to, mapping); // Try to propagate any dbrefs across this mapping. diff --git a/src/jalview/io/vamsas/Tree.java b/src/jalview/io/vamsas/Tree.java index dbfaf37..40d9f7c 100644 --- a/src/jalview/io/vamsas/Tree.java +++ b/src/jalview/io/vamsas/Tree.java @@ -35,10 +35,10 @@ import jalview.datamodel.SeqCigar; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceI; import jalview.datamodel.SequenceNode; -import jalview.gui.AlignViewport; import jalview.gui.TreePanel; import jalview.io.NewickFile; import jalview.io.VamsasAppDatastore; +import jalview.viewmodel.AlignmentViewport; import uk.ac.vamsas.client.Vobject; import uk.ac.vamsas.objects.core.AlignmentSequence; import uk.ac.vamsas.objects.core.Entry; @@ -510,7 +510,7 @@ public class Tree extends DatastoreItem */ public Object[] recoverInputData(Provenance tp) { - AlignViewport javport = null; + AlignmentViewport javport = null; jalview.datamodel.AlignmentI jal = null; jalview.datamodel.CigarArray view = null; for (int pe = 0; pe < tp.getEntryCount(); pe++) @@ -604,7 +604,7 @@ public class Tree extends DatastoreItem return null; } - private AlignViewport getViewport(Vobject v_parent) + private AlignmentViewport getViewport(Vobject v_parent) { if (v_parent instanceof uk.ac.vamsas.objects.core.Alignment) { diff --git a/src/jalview/javascript/JsSelectionSender.java b/src/jalview/javascript/JsSelectionSender.java index d9e1b98..9714351 100644 --- a/src/jalview/javascript/JsSelectionSender.java +++ b/src/jalview/javascript/JsSelectionSender.java @@ -94,9 +94,7 @@ public class JsSelectionSender extends JSFunctionExec implements int d = 0, r = -1; for (int i = 0; i < cols.length; i++) { - cols[i] = "" - + (1 + ((Integer) colsel.getSelected().elementAt(i)) - .intValue()); + cols[i] = "" + (1 + colsel.getSelected().get(i).intValue()); } } else diff --git a/src/jalview/jbgui/GAlignFrame.java b/src/jalview/jbgui/GAlignFrame.java index 630c962..44770a2 100755 --- a/src/jalview/jbgui/GAlignFrame.java +++ b/src/jalview/jbgui/GAlignFrame.java @@ -37,10 +37,14 @@ import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.util.HashMap; +import java.util.Map; +import javax.swing.AbstractAction; import javax.swing.BorderFactory; import javax.swing.ButtonGroup; import javax.swing.JCheckBoxMenuItem; +import javax.swing.JComponent; import javax.swing.JInternalFrame; import javax.swing.JLabel; import javax.swing.JMenu; @@ -50,6 +54,7 @@ import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JRadioButtonMenuItem; import javax.swing.JTabbedPane; +import javax.swing.KeyStroke; import javax.swing.SwingUtilities; import javax.swing.event.ChangeEvent; import javax.swing.event.MenuEvent; @@ -386,6 +391,8 @@ public class GAlignFrame extends JInternalFrame private boolean showAutoCalculatedAbove = false; + private Map accelerators = new HashMap(); + public GAlignFrame() { try @@ -427,6 +434,8 @@ public class GAlignFrame extends JInternalFrame reload.setMnemonic('R'); } + // setKeyBindings(); + if (jalview.gui.UserDefinedColours.getUserColourSchemes() != null) { java.util.Enumeration userColours = jalview.gui.UserDefinedColours @@ -508,6 +517,30 @@ public class GAlignFrame extends JInternalFrame } + /** + * Set key bindings (recommended for Swing over key accelerators). + */ + private void setKeyBindings() + { + /* + * Experiment using Cmd-Alt/K (unmapped) as a synonym for Cmd-Alt/I (invert + * column selection) + */ + this.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put( + KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_K, Toolkit + .getDefaultToolkit().getMenuShortcutKeyMask() + | java.awt.event.KeyEvent.ALT_MASK, false), + "INV_SEQ_SEL"); + this.getActionMap().put("INV_SEQ_SEL", new AbstractAction() + { + @Override + public void actionPerformed(ActionEvent e) + { + invertColSel_actionPerformed(null); + } + }); + } + public void setColourSelected(String defaultColour) { @@ -609,10 +642,12 @@ public class GAlignFrame extends JInternalFrame { fileMenu.setText(MessageManager.getString("action.file")); saveAs.setText(MessageManager.getString("action.save_as") + "..."); - saveAs.setAccelerator(javax.swing.KeyStroke.getKeyStroke( + KeyStroke keyStroke = javax.swing.KeyStroke.getKeyStroke( java.awt.event.KeyEvent.VK_S, Toolkit.getDefaultToolkit() .getMenuShortcutKeyMask() - | java.awt.event.KeyEvent.SHIFT_MASK, false)); + | java.awt.event.KeyEvent.SHIFT_MASK, false); + saveAs.setAccelerator(keyStroke); + accelerators.put(keyStroke, saveAs); saveAs.addActionListener(new ActionListener() { @Override @@ -668,9 +703,11 @@ public class GAlignFrame extends JInternalFrame }); invertSequenceMenuItem.setText(MessageManager .getString("action.invert_sequence_selection")); - invertSequenceMenuItem.setAccelerator(javax.swing.KeyStroke + keyStroke = javax.swing.KeyStroke .getKeyStroke(java.awt.event.KeyEvent.VK_I, Toolkit - .getDefaultToolkit().getMenuShortcutKeyMask(), false)); + .getDefaultToolkit().getMenuShortcutKeyMask(), false); + invertSequenceMenuItem.setAccelerator(keyStroke); + accelerators.put(keyStroke, invertSequenceMenuItem); invertSequenceMenuItem .addActionListener(new java.awt.event.ActionListener() { @@ -3176,4 +3213,9 @@ public class GAlignFrame extends JInternalFrame { this.annotationSortOrder = annotationSortOrder; } + + public Map getAccelerators() + { + return this.accelerators; + } } diff --git a/src/jalview/structure/StructureSelectionManager.java b/src/jalview/structure/StructureSelectionManager.java index 945e08d..2dbe360 100644 --- a/src/jalview/structure/StructureSelectionManager.java +++ b/src/jalview/structure/StructureSelectionManager.java @@ -837,16 +837,13 @@ public class StructureSelectionManager /** * Remove each of the given codonFrames from the stored set (if present). * - * @param codonFrames + * @param set */ - public void removeMappings(AlignedCodonFrame[] codonFrames) + public void removeMappings(Set set) { - if (codonFrames != null) + if (set != null) { - for (AlignedCodonFrame acf : codonFrames) - { - seqmappings.remove(acf); - } + seqmappings.removeAll(set); } } @@ -854,16 +851,21 @@ public class StructureSelectionManager * Add each of the given codonFrames to the stored set (if not aready * present). * - * @param codonFrames + * @param set */ - public void addMappings(AlignedCodonFrame[] codonFrames) + public void addMappings(Set set) { - if (codonFrames != null) + if (set != null) { - for (AlignedCodonFrame acf : codonFrames) - { - seqmappings.add(acf); - } + seqmappings.addAll(set); + } + } + + public void addMapping(AlignedCodonFrame acf) + { + if (acf != null) + { + seqmappings.add(acf); } } @@ -999,24 +1001,22 @@ public class StructureSelectionManager * * @param command * @param undo - * @param alignmentI + * @param mapTo * @param gapChar * @return */ - public CommandI mapCommand(CommandI command, - boolean undo, - final AlignmentI alignmentI, char gapChar) + public CommandI mapCommand(CommandI command, boolean undo, + final AlignmentI mapTo, char gapChar) { if (command instanceof EditCommand) { return MappingUtils.mapEditCommand((EditCommand) command, undo, - alignmentI, gapChar, - seqmappings); + mapTo, gapChar, seqmappings); } else if (command instanceof OrderCommand) { return MappingUtils.mapOrderCommand((OrderCommand) command, undo, - alignmentI, seqmappings); + mapTo, seqmappings); } return null; } diff --git a/src/jalview/util/Comparison.java b/src/jalview/util/Comparison.java index 259a5d8..b9a95be 100644 --- a/src/jalview/util/Comparison.java +++ b/src/jalview/util/Comparison.java @@ -31,7 +31,14 @@ public class Comparison private static final int TO_UPPER_CASE = 'a' - 'A'; - public static final String GapChars = " .-"; + private static final char GAP_SPACE = ' '; + + private static final char GAP_DOT = '.'; + + private static final char GAP_DASH = '-'; + + public static final String GapChars = new String(new char[] + { GAP_SPACE, GAP_DOT, GAP_DASH }); /** * DOCUMENT ME! @@ -235,7 +242,7 @@ public class Comparison */ public static final boolean isGap(char c) { - return (c == '-' || c == '.' || c == ' ') ? true : false; + return (c == GAP_DASH || c == GAP_DOT || c == GAP_SPACE) ? true : false; } /** diff --git a/src/jalview/util/MappingUtils.java b/src/jalview/util/MappingUtils.java index 466aeb8..7dd0b5c 100644 --- a/src/jalview/util/MappingUtils.java +++ b/src/jalview/util/MappingUtils.java @@ -10,10 +10,13 @@ import jalview.commands.OrderCommand; import jalview.datamodel.AlignedCodonFrame; import jalview.datamodel.AlignmentI; import jalview.datamodel.AlignmentOrder; +import jalview.datamodel.ColumnSelection; import jalview.datamodel.SearchResults; +import jalview.datamodel.SearchResults.Match; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; +import jalview.gui.AlignViewport; import java.util.ArrayList; import java.util.HashMap; @@ -63,21 +66,29 @@ public final class MappingUtils * * @param command * @param undo - * @param alignment + * @param mapTo * @param gapChar * @param mappings * @return */ public static EditCommand mapEditCommand(EditCommand command, - boolean undo, final AlignmentI alignment, char gapChar, + boolean undo, final AlignmentI mapTo, char gapChar, Set mappings) { /* + * For now, only support mapping from protein edits to cDna + */ + if (!mapTo.isNucleotide()) + { + return null; + } + + /* * Cache a copy of the target sequences so we can mimic successive edits on * them. This lets us compute mappings for all edits in the set. */ Map targetCopies = new HashMap(); - for (SequenceI seq : alignment.getSequences()) + for (SequenceI seq : mapTo.getSequences()) { SequenceI ds = seq.getDatasetSequence(); if (ds != null) @@ -88,12 +99,12 @@ public final class MappingUtils targetCopies.put(ds, copy); } } - + /* * Compute 'source' sequences as they were before applying edits: */ Map originalSequences = command.priorState(undo); - + EditCommand result = new EditCommand(); Iterator edits = command.getEditIterator(!undo); while (edits.hasNext()) @@ -102,15 +113,14 @@ public final class MappingUtils if (edit.getAction() == Action.CUT || edit.getAction() == Action.PASTE) { - mapCutOrPaste(edit, undo, alignment.getSequences(), result, - mappings); + mapCutOrPaste(edit, undo, mapTo.getSequences(), result, mappings); } else if (edit.getAction() == Action.INSERT_GAP || edit.getAction() == Action.DELETE_GAP) { mapInsertOrDelete(edit, undo, originalSequences, - alignment.getSequences(), - targetCopies, gapChar, result, mappings); + mapTo.getSequences(), targetCopies, gapChar, result, + mappings); } } return result.getSize() > 0 ? result : null; @@ -139,7 +149,7 @@ public final class MappingUtils EditCommand result, Set mappings) { Action action = edit.getAction(); - + /* * Invert sense of action if an Undo. */ @@ -162,12 +172,12 @@ public final class MappingUtils } final SequenceI actedOn = originalSequences.get(ds); final int seqpos = actedOn.findPosition(editPos); - + /* * Determine all mappings from this position to mapped sequences. */ SearchResults sr = buildSearchResults(seq, seqpos, mappings); - + if (!sr.isEmpty()) { for (SequenceI targetSeq : targetSeqs) @@ -184,7 +194,7 @@ public final class MappingUtils { final int ratio = 3; // TODO: compute this - how? final int mappedCount = count * ratio; - + /* * Shift Delete start position left, as it acts on positions to its * right. @@ -194,7 +204,7 @@ public final class MappingUtils Edit e = result.new Edit(action, new SequenceI[] { targetSeq }, mappedEditPos, mappedCount, gapChar); result.addEdit(e); - + /* * and 'apply' the edit to our copy of its target sequence */ @@ -255,22 +265,24 @@ public final class MappingUtils } /** - * Returns a (possibly empty) SequenceGroup containing any sequences the + * Returns a (possibly empty) SequenceGroup containing any sequences in the * mapped viewport corresponding to the given group in the source viewport. * * @param sg - * @param av - * @param mapped + * @param mapFrom + * @param mapTo * @return */ public static SequenceGroup mapSequenceGroup(SequenceGroup sg, - AlignViewportI av, AlignViewportI mapped) + AlignViewportI mapFrom, AlignViewportI mapTo) { /* - * Map sequence selection. Note the SequenceGroup holds aligned sequences, - * the mappings hold dataset sequences. + * Note the SequenceGroup holds aligned sequences, the mappings hold dataset + * sequences. */ - AlignedCodonFrame[] codonFrames = av.getAlignment() + boolean targetIsNucleotide = mapTo.isNucleotide(); + AlignViewportI protein = targetIsNucleotide ? mapFrom : mapTo; + Set codonFrames = protein.getAlignment() .getCodonFrames(); /* @@ -284,12 +296,13 @@ public final class MappingUtils { for (AlignedCodonFrame acf : codonFrames) { - SequenceI dnaSeq = acf.getDnaForAaSeq(selected); - if (dnaSeq != null) + SequenceI mappedSequence = targetIsNucleotide ? acf + .getDnaForAaSeq(selected) : acf.getAaForDnaSeq(selected); + if (mappedSequence != null) { - for (SequenceI seq : mapped.getAlignment().getSequences()) + for (SequenceI seq : mapTo.getAlignment().getSequences()) { - if (seq.getDatasetSequence() == dnaSeq) + if (seq.getDatasetSequence() == mappedSequence) { mappedGroup.addSequence(seq, false); break; @@ -316,8 +329,7 @@ public final class MappingUtils * @return */ public static CommandI mapOrderCommand(OrderCommand command, - boolean undo, AlignmentI mapTo, - Set mappings) + boolean undo, AlignmentI mapTo, Set mappings) { SequenceI[] sortOrder = command.getSequenceOrder(undo); List mappedOrder = new ArrayList(); @@ -326,12 +338,19 @@ public final class MappingUtils { for (AlignedCodonFrame acf : mappings) { - SequenceI dnaSeq = acf.getDnaForAaSeq(seq); - if (dnaSeq != null) + /* + * Try protein-to-Dna, failing that try dna-to-protein + */ + SequenceI mappedSeq = acf.getDnaForAaSeq(seq); + if (mappedSeq == null) + { + mappedSeq = acf.getAaForDnaSeq(seq); + } + if (mappedSeq != null) { for (SequenceI seq2 : mapTo.getSequences()) { - if (seq2.getDatasetSequence() == dnaSeq) + if (seq2.getDatasetSequence() == mappedSeq) { mappedOrder.add(seq2); j++; @@ -378,4 +397,82 @@ public final class MappingUtils return result; } + /** + * Returns a ColumnSelection in the 'mapTo' view which corresponds to the + * given selection in the 'mapFrom' view. We assume one is nucleotide, the + * other is protein (and holds the mappings from codons to protein residues). + * + * @param colsel + * @param mapFrom + * @param mapTo + * @return + */ + public static ColumnSelection mapColumnSelection(ColumnSelection colsel, + AlignViewportI mapFrom, AlignViewport mapTo) + { + boolean targetIsNucleotide = mapTo.isNucleotide(); + AlignViewportI protein = targetIsNucleotide ? mapFrom : mapTo; + Set codonFrames = protein.getAlignment() + .getCodonFrames(); + ColumnSelection mappedColumns = new ColumnSelection(); + char fromGapChar = mapFrom.getAlignment().getGapCharacter(); + + for (int col : colsel.getSelected()) + { + int mappedToMin = Integer.MAX_VALUE; + int mappedToMax = Integer.MIN_VALUE; + + /* + * For each sequence in the 'from' alignment + */ + for (SequenceI fromSeq : mapFrom.getAlignment().getSequences()) + { + /* + * Ignore gaps (unmapped anyway) + */ + if (fromSeq.getCharAt(col) == fromGapChar) + { + continue; + } + + /* + * Get the residue position and find the mapped position. + */ + int residuePos = fromSeq.findPosition(col); + SearchResults sr = buildSearchResults(fromSeq, residuePos, + codonFrames); + for (Match m : sr.getResults()) + { + int mappedStartResidue = m.getStart(); + int mappedEndResidue = m.getEnd(); + SequenceI mappedSeq = m.getSequence(); + + /* + * Locate the aligned sequence whose dataset is mappedSeq. + */ + for (SequenceI toSeq : mapTo.getAlignment().getSequences()) + { + if (toSeq.getDatasetSequence() == mappedSeq) + { + int mappedStartCol = toSeq.findIndex(mappedStartResidue); + int mappedEndCol = toSeq.findIndex(mappedEndResidue); + mappedToMin = Math.min(mappedToMin, mappedStartCol); + mappedToMax = Math.max(mappedToMax, mappedEndCol); + // System.out.println(fromSeq.getName() + " mapped to cols " + // + mappedStartCol + ":" + mappedEndCol); + } + } + } + } + /* + * Add mapped columns to mapped selection (converting base 1 to base 0) + */ + for (int i = mappedToMin; i <= mappedToMax; i++) + { + mappedColumns.addElement(i - 1); + } + } + return mappedColumns; + } + } diff --git a/src/jalview/util/ShiftList.java b/src/jalview/util/ShiftList.java index 2b3a8a4..3b8c68f 100644 --- a/src/jalview/util/ShiftList.java +++ b/src/jalview/util/ShiftList.java @@ -20,7 +20,8 @@ */ package jalview.util; -import java.util.*; +import java.util.ArrayList; +import java.util.List; /** * ShiftList Simple way of mapping a linear series to a new linear range with @@ -29,11 +30,11 @@ import java.util.*; */ public class ShiftList { - public Vector shifts; + private List shifts; public ShiftList() { - shifts = new Vector(); + shifts = new ArrayList(); } /** @@ -48,15 +49,14 @@ public class ShiftList { int sidx = 0; int[] rshift = null; - while (sidx < shifts.size() - && (rshift = (int[]) shifts.elementAt(sidx))[0] < pos) + while (sidx < shifts.size() && (rshift = shifts.get(sidx))[0] < pos) { sidx++; } if (sidx == shifts.size()) { - shifts.insertElementAt(new int[] - { pos, shift }, sidx); + shifts.add(sidx, new int[] + { pos, shift }); } else { @@ -81,7 +81,7 @@ public class ShiftList int sidx = 0; int rshift[]; while (sidx < shifts.size() - && (rshift = ((int[]) shifts.elementAt(sidx++)))[0] <= pos) + && (rshift = (shifts.get(sidx++)))[0] <= pos) { shifted += rshift[1]; } @@ -93,7 +93,7 @@ public class ShiftList */ public void clear() { - shifts.removeAllElements(); + shifts.clear(); } /** @@ -108,10 +108,10 @@ public class ShiftList { for (int i = 0, j = shifts.size(); i < j; i++) { - int[] sh = (int[]) shifts.elementAt(i); + int[] sh = shifts.get(i); if (sh != null) { - inverse.shifts.addElement(new int[] + inverse.shifts.add(new int[] { sh[0], -sh[1] }); } } @@ -120,8 +120,8 @@ public class ShiftList } /** - * parse a 1d map of position 1 getShifts() + { + return shifts; + } } diff --git a/src/jalview/viewmodel/AlignmentViewport.java b/src/jalview/viewmodel/AlignmentViewport.java index ed63e0f..7145f7b 100644 --- a/src/jalview/viewmodel/AlignmentViewport.java +++ b/src/jalview/viewmodel/AlignmentViewport.java @@ -37,6 +37,7 @@ import jalview.schemes.Blosum62ColourScheme; import jalview.schemes.ColourSchemeI; import jalview.schemes.PIDColourScheme; import jalview.schemes.ResidueProperties; +import jalview.util.MappingUtils; import jalview.workers.AlignCalcManager; import jalview.workers.ConsensusThread; import jalview.workers.StrucConsensusThread; @@ -60,9 +61,10 @@ import java.util.Vector; public abstract class AlignmentViewport implements AlignViewportI { /* - * A viewport that is a slave of (driven by) this one in some sense. + * A viewport that hosts the cDna view of this (protein), or vice versa (if + * set). */ - AlignViewportI slave = null; + AlignViewportI codingComplement = null; /** * alignment displayed in the viewport. Please use get/setter @@ -963,6 +965,17 @@ public abstract class AlignmentViewport implements AlignViewportI hideSequence(seqs); + AlignViewportI peer = getCodingComplement(); + if (peer != null) + { + SequenceGroup mappedGroup = MappingUtils.mapSequenceGroup( + selectionGroup, this, peer); + ((AlignmentViewport) peer).hideSequence(mappedGroup + .getSequencesInOrder(peer.getAlignment())); + peer.setSelectionGroup(null); + + } + setSelectionGroup(null); } @@ -1650,21 +1663,36 @@ public abstract class AlignmentViewport implements AlignViewportI }; @Override - public AlignViewportI getSlave() + public AlignViewportI getCodingComplement() { - return this.slave; + return this.codingComplement; } + /** + * Set this as the (cDna/protein) complement of the given viewport. Also + * ensures the reverse relationship is set on the given viewport. + */ @Override - public void setSlave(AlignViewportI sl) + public void setCodingComplement(AlignViewportI av) { - if (this == sl.getSlave()) + if (this == av) { - System.err.println("Ignoring recursive setSlave request"); + System.err.println("Ignoring recursive setCodingComplement request"); } else { - this.slave = sl; + this.codingComplement = av; + // avoid infinite recursion! + if (av.getCodingComplement() != this) + { + av.setCodingComplement(this); + } } } + + @Override + public boolean isNucleotide() + { + return getAlignment() == null ? false : getAlignment().isNucleotide(); + } } diff --git a/src/jalview/ws/AWSThread.java b/src/jalview/ws/AWSThread.java index dd7ef7c..c775059 100644 --- a/src/jalview/ws/AWSThread.java +++ b/src/jalview/ws/AWSThread.java @@ -31,6 +31,9 @@ import jalview.gui.FeatureRenderer.FeatureRendererSettings; import jalview.gui.WebserviceInfo; import jalview.util.MessageManager; +import java.util.LinkedHashSet; +import java.util.Set; + public abstract class AWSThread extends Thread { @@ -57,7 +60,7 @@ public abstract class AWSThread extends Thread /** * dataset sequence relationships to be propagated onto new results */ - protected AlignedCodonFrame[] codonframe = null; + protected Set codonframe = null; /** * are there jobs still running in this thread. @@ -295,14 +298,12 @@ public abstract class AWSThread extends Thread SequenceI[] alignment = al.getSequencesArray(); for (int sq = 0; sq < alignment.length; sq++) { - for (int i = 0; i < codonframe.length; i++) + for (AlignedCodonFrame acf : codonframe) { - AlignedCodonFrame acf = codonframe[i]; final SequenceI seq = alignment[sq]; if (acf != null && acf.involvesSequence(seq)) { al.addCodonFrame(acf); - codonframe[i] = null; break; } } @@ -370,12 +371,12 @@ public abstract class AWSThread extends Thread WsUrl = wsurl2; if (alframe != null) { - AlignedCodonFrame[] cf = alframe.getViewport().getAlignment() + Set cf = alframe.getViewport().getAlignment() .getCodonFrames(); if (cf != null) { - codonframe = new AlignedCodonFrame[cf.length]; - System.arraycopy(cf, 0, codonframe, 0, cf.length); + codonframe = new LinkedHashSet(); + codonframe.addAll(cf); } } } diff --git a/test/jalview/analysis/AlignmentUtilsTests.java b/test/jalview/analysis/AlignmentUtilsTests.java index 66f99f3..d1300fe 100644 --- a/test/jalview/analysis/AlignmentUtilsTests.java +++ b/test/jalview/analysis/AlignmentUtilsTests.java @@ -167,15 +167,15 @@ public class AlignmentUtilsTests /* * Check two mappings (one for Mouse, one for Human) */ - assertEquals(2, protein.getCodonFrames().length); - assertEquals(1, protein.getCodonFrame(protein.getSequenceAt(0)).length); - assertEquals(1, protein.getCodonFrame(protein.getSequenceAt(1)).length); + assertEquals(2, protein.getCodonFrames().size()); + assertEquals(1, protein.getCodonFrame(protein.getSequenceAt(0)).size()); + assertEquals(1, protein.getCodonFrame(protein.getSequenceAt(1)).size()); /* * Inspect mapping for Human protein */ - AlignedCodonFrame humanMapping = protein.getCodonFrame(protein - .getSequenceAt(0))[0]; + AlignedCodonFrame humanMapping = protein.getCodonFrame( + protein.getSequenceAt(0)).get(0); assertEquals(1, humanMapping.getdnaSeqs().length); assertEquals(cdna1.getSequenceAt(1).getDatasetSequence(), humanMapping.getdnaSeqs()[0]); @@ -192,8 +192,8 @@ public class AlignmentUtilsTests /* * Inspect mappings for Mouse protein */ - AlignedCodonFrame mouseMapping1 = protein.getCodonFrame(protein - .getSequenceAt(1))[0]; + AlignedCodonFrame mouseMapping1 = protein.getCodonFrame( + protein.getSequenceAt(1)).get(0); assertEquals(2, mouseMapping1.getdnaSeqs().length); assertEquals(cdna1.getSequenceAt(0).getDatasetSequence(), mouseMapping1.getdnaSeqs()[0]); @@ -241,15 +241,15 @@ public class AlignmentUtilsTests /* * Check two mappings (one for Mouse, one for Human) */ - assertEquals(2, protein.getCodonFrames().length); - assertEquals(1, protein.getCodonFrame(protein.getSequenceAt(0)).length); - assertEquals(1, protein.getCodonFrame(protein.getSequenceAt(1)).length); + assertEquals(2, protein.getCodonFrames().size()); + assertEquals(1, protein.getCodonFrame(protein.getSequenceAt(0)).size()); + assertEquals(1, protein.getCodonFrame(protein.getSequenceAt(1)).size()); /* * Inspect mapping for Human protein - should map to 2nd and 4th cDNA seqs */ - AlignedCodonFrame humanMapping = protein.getCodonFrame(protein - .getSequenceAt(0))[0]; + AlignedCodonFrame humanMapping = protein.getCodonFrame( + protein.getSequenceAt(0)).get(0); assertEquals(2, humanMapping.getdnaSeqs().length); assertEquals(cdna1.getSequenceAt(1).getDatasetSequence(), humanMapping.getdnaSeqs()[0]); @@ -276,8 +276,8 @@ public class AlignmentUtilsTests /* * Inspect mapping for Mouse protein - should map to 1st/3rd/5th cDNA seqs */ - AlignedCodonFrame mouseMapping = protein.getCodonFrame(protein - .getSequenceAt(1))[0]; + AlignedCodonFrame mouseMapping = protein.getCodonFrame( + protein.getSequenceAt(1)).get(0); assertEquals(3, mouseMapping.getdnaSeqs().length); assertEquals(cdna1.getSequenceAt(0).getDatasetSequence(), mouseMapping.getdnaSeqs()[0]); diff --git a/test/jalview/analysis/TestAlignSeq.java b/test/jalview/analysis/TestAlignSeq.java index ca4f18d..6f331ff 100644 --- a/test/jalview/analysis/TestAlignSeq.java +++ b/test/jalview/analysis/TestAlignSeq.java @@ -20,7 +20,9 @@ */ package jalview.analysis; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import jalview.datamodel.Mapping; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceI; @@ -74,4 +76,13 @@ public class TestAlignSeq } } + @Test + public void testExtractGaps() + { + assertNull(AlignSeq.extractGaps(null, null)); + assertNull(AlignSeq.extractGaps(". -", null)); + assertNull(AlignSeq.extractGaps(null, "AB-C")); + + assertEquals("ABCD", AlignSeq.extractGaps(" .-", ". -A-B.C D.")); + } } diff --git a/test/jalview/datamodel/ColumnSelectionTest.java b/test/jalview/datamodel/ColumnSelectionTest.java new file mode 100644 index 0000000..228156a --- /dev/null +++ b/test/jalview/datamodel/ColumnSelectionTest.java @@ -0,0 +1,48 @@ +package jalview.datamodel; + +import static org.junit.Assert.assertEquals; + +import java.util.List; + +import org.junit.Test; + +public class ColumnSelectionTest +{ + + @Test + public void testAddElement() + { + ColumnSelection cs = new ColumnSelection(); + cs.addElement(2); + cs.addElement(5); + List sel = cs.getSelected(); + assertEquals(2, sel.size()); + assertEquals(new Integer(2), sel.get(0)); + assertEquals(new Integer(5), sel.get(1)); + } + + /** + * Test the remove method - in particular to verify that remove(int i) removes + * the element whose value is i, _NOT_ the i'th element. + */ + @Test + public void testRemoveElement() + { + ColumnSelection cs = new ColumnSelection(); + cs.addElement(2); + cs.addElement(5); + + // removing elements not in the list has no effect + cs.removeElement(0); + cs.removeElement(1); + List sel = cs.getSelected(); + assertEquals(2, sel.size()); + assertEquals(new Integer(2), sel.get(0)); + assertEquals(new Integer(5), sel.get(1)); + + // removing an element in the list removes it + cs.removeElement(2); + assertEquals(1, sel.size()); + assertEquals(new Integer(5), sel.get(0)); + } +} diff --git a/test/jalview/datamodel/SequenceTest.java b/test/jalview/datamodel/SequenceTest.java index 2a23104..3ccf88c 100644 --- a/test/jalview/datamodel/SequenceTest.java +++ b/test/jalview/datamodel/SequenceTest.java @@ -5,6 +5,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; +import java.util.Arrays; import java.util.List; import org.junit.Before; @@ -137,6 +138,38 @@ public class SequenceTest assertEquals(0, seq.getEnd()); // ?? } + /** + * Tests for the method that returns an alignment column position (base 1) for + * a given sequence position (base 1). + */ + @Test + public void testFindIndex() + { + SequenceI seq = new Sequence("test", "ABCDEF"); + assertEquals(0, seq.findIndex(0)); + assertEquals(1, seq.findIndex(1)); + assertEquals(5, seq.findIndex(5)); + assertEquals(6, seq.findIndex(6)); + assertEquals(6, seq.findIndex(9)); + + seq = new Sequence("test", "-A--B-C-D-E-F--"); + assertEquals(2, seq.findIndex(1)); + assertEquals(5, seq.findIndex(2)); + assertEquals(7, seq.findIndex(3)); + + // before start returns 0 + assertEquals(0, seq.findIndex(0)); + assertEquals(0, seq.findIndex(-1)); + + // beyond end returns last residue column + assertEquals(13, seq.findIndex(99)); + + } + + /** + * Tests for the method that returns a dataset sequence position (base 1) for + * an aligned column position (base 0). + */ @Test public void testFindPosition() { @@ -202,4 +235,16 @@ public class SequenceTest // for static method see StringUtilsTest } + + /** + * Test the method that returns an array of aligned sequence positions where + * the array index is the data sequence position (both base 0). + */ + @Test + public void testGapMap() + { + SequenceI seq = new Sequence("test", "-A--B-CD-E--F-"); + seq.createDatasetSequence(); + assertEquals("[1, 4, 6, 7, 9, 12]", Arrays.toString(seq.gapMap())); + } } diff --git a/test/jalview/util/ShiftListTest.java b/test/jalview/util/ShiftListTest.java new file mode 100644 index 0000000..f680d6c --- /dev/null +++ b/test/jalview/util/ShiftListTest.java @@ -0,0 +1,35 @@ +package jalview.util; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +public class ShiftListTest +{ + + @Test + public void testParseMap() + { + assertNull(ShiftList.parseMap(null)); + assertNull(ShiftList.parseMap(new int[] + {})); + + /* + * Gap map showing residues in aligned positions 2,3,6,8,9,10,12 + */ + int[] gm = new int[] + { 2, 3, 6, 8, 9, 10, 12 }; + List shifts = ShiftList.parseMap(gm).getShifts(); + assertEquals(4, shifts.size()); + + // TODO are these results (which pass) correct?? + assertEquals("[0, 2]", Arrays.toString(shifts.get(0))); + assertEquals("[4, 2]", Arrays.toString(shifts.get(1))); + assertEquals("[7, 1]", Arrays.toString(shifts.get(2))); + assertEquals("[11, 1]", Arrays.toString(shifts.get(3))); + } +} -- 1.7.10.2