X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fdatamodel%2FAlignmentView.java;h=6ab71c74530268fe5f7427156cfe077813d23a9c;hb=HEAD;hp=c5019d1aec59e94643326637f47377798c8a572d;hpb=b2f9a8d7bce642ff4011bc6d49e02bb0569fbb11;p=jalview.git diff --git a/src/jalview/datamodel/AlignmentView.java b/src/jalview/datamodel/AlignmentView.java index c5019d1..6ab71c7 100644 --- a/src/jalview/datamodel/AlignmentView.java +++ b/src/jalview/datamodel/AlignmentView.java @@ -1,29 +1,31 @@ /* - * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.1) - * Copyright (C) 2014 The Jalview Authors + * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) + * Copyright (C) $$Year-Rel$$ The Jalview Authors * * 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 - * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + * 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. * - * You should have received a copy of the GNU General Public License along with Jalview. If not, see . + * You should have received a copy of the GNU General Public License + * along with Jalview. If not, see . * The Jalview Authors are detailed in the 'AUTHORS' file. */ package jalview.datamodel; +import jalview.util.MessageManager; import jalview.util.ShiftList; import java.io.PrintStream; -import java.util.Enumeration; +import java.util.ArrayList; import java.util.List; -import java.util.Vector; /** * Transient object compactly representing a 'view' of an alignment - with @@ -44,11 +46,13 @@ public class AlignmentView * one or more ScGroup objects, which are referenced by each seqCigar's group * membership */ - private Vector scGroups; + private List scGroups = null; + + private boolean isNa = false; - private boolean isNa=false; /** * false if the view concerns peptides + * * @return */ public boolean isNa() @@ -64,13 +68,51 @@ public class AlignmentView */ private class ScGroup { - public Vector seqs; + public List seqs; public SequenceGroup sg; ScGroup() { - seqs = new Vector(); + seqs = new ArrayList<>(); + } + + /** + * @param seq + * @return true if seq was not a member before and was added to group + */ + public boolean add(SeqCigar seq) + { + if (!seq.isMemberOf(this)) + { + seqs.add(seq); + seq.setGroupMembership(this); + return true; + } + else + { + return false; + } + } + + /** + * + * @param seq + * @return true if seq was a member and was removed from group + */ + public boolean remove(SeqCigar seq) + { + if (seq.removeGroupMembership(this)) + { + seqs.remove(seq); + return true; + } + return false; + } + + public int size() + { + return seqs.size(); } } @@ -78,7 +120,7 @@ public class AlignmentView * vector of selected seqCigars. This vector is also referenced by each * seqCigar contained in it. */ - private Vector selected; + private ScGroup selected; /** * Construct an alignmentView from a live jalview alignment view. Note - @@ -98,17 +140,17 @@ public class AlignmentView * - when set, any groups on the given alignment will be marked on * the view */ - public AlignmentView(AlignmentI alignment, - ColumnSelection columnSelection, SequenceGroup selection, - boolean hasHiddenColumns, boolean selectedRegionOnly, - boolean recordGroups) + public AlignmentView(AlignmentI alignment, HiddenColumns hidden, + SequenceGroup selection, boolean hasHiddenColumns, + boolean selectedRegionOnly, boolean recordGroups) { // refactored from AlignViewport.getAlignmentView(selectedOnly); this(new jalview.datamodel.CigarArray(alignment, - (hasHiddenColumns ? columnSelection : null), + (hasHiddenColumns ? hidden : null), (selectedRegionOnly ? selection : null)), - (selectedRegionOnly && selection != null) ? selection - .getStartRes() : 0); + (selectedRegionOnly && selection != null) + ? selection.getStartRes() + : 0); isNa = alignment.isNucleotide(); // walk down SeqCigar array and Alignment Array - optionally restricted by // selected region. @@ -118,37 +160,33 @@ public class AlignmentView SequenceI[] selseqs; if (selection != null && selection.getSize() > 0) { - List sel = selection.getSequences(null); - this.selected = new Vector(); - selseqs = selection - .getSequencesInOrder(alignment, selectedRegionOnly); + this.selected = new ScGroup(); + selseqs = selection.getSequencesInOrder(alignment, + selectedRegionOnly); } else { selseqs = alignment.getSequencesArray(); } + List> seqsets = new ArrayList<>(); // get the alignment's group list and make a copy - Vector grps = new Vector(); + List grps = new ArrayList<>(); List gg = alignment.getGroups(); grps.addAll(gg); ScGroup[] sgrps = null; boolean addedgps[] = null; if (grps != null) { - SequenceGroup sg; if (selection != null && selectedRegionOnly) { // trim annotation to the region being stored. // strip out any groups that do not actually intersect with the // visible and selected region int ssel = selection.getStartRes(), esel = selection.getEndRes(); - Vector isg = new Vector(); - Enumeration en = grps.elements(); - while (en.hasMoreElements()) + List isg = new ArrayList<>(); + for (SequenceGroup sg : grps) { - sg = (SequenceGroup) en.nextElement(); - if (!(sg.getStartRes() > esel || sg.getEndRes() < ssel)) { // adjust bounds of new group, if necessary. @@ -163,7 +201,7 @@ public class AlignmentView sg.setStartRes(sg.getStartRes() - ssel + 1); sg.setEndRes(sg.getEndRes() - ssel + 1); - isg.addElement(sg); + isg.add(sg); } } grps = isg; @@ -173,13 +211,15 @@ public class AlignmentView addedgps = new boolean[grps.size()]; for (int g = 0; g < sgrps.length; g++) { - sg = (SequenceGroup) grps.elementAt(g); + SequenceGroup sg = grps.get(g); sgrps[g] = new ScGroup(); sgrps[g].sg = new SequenceGroup(sg); addedgps[g] = false; - grps.setElementAt(sg.getSequences(null), g); + // can't set entry 0 in an empty list + // seqsets.set(g, sg.getSequences(null)); + seqsets.add(sg.getSequences()); } - // grps now contains vectors (should be sets) for each group, so we can + // seqsets now contains vectors (should be sets) for each group, so we can // track when we've done with the group } int csi = 0; @@ -190,26 +230,24 @@ public class AlignmentView if (selection != null && selection.getSize() > 0 && !selectedRegionOnly) { - sequences[csi].setGroupMembership(selected); - selected.addElement(sequences[csi]); + selected.add(sequences[csi]); } - if (grps != null) + if (seqsets != null) { for (int sg = 0; sg < sgrps.length; sg++) { - if (((Vector) grps.elementAt(sg)).contains(selseqs[i])) + if ((seqsets.get(sg)).contains(selseqs[i])) { - sequences[csi].setGroupMembership(sgrps[sg]); sgrps[sg].sg.deleteSequence(selseqs[i], false); - sgrps[sg].seqs.addElement(sequences[csi]); + sgrps[sg].add(sequences[csi]); if (!addedgps[sg]) { if (scGroups == null) { - scGroups = new Vector(); + scGroups = new ArrayList<>(); } addedgps[sg] = true; - scGroups.addElement(sgrps[sg]); + scGroups.add(sgrps[sg]); } } } @@ -291,14 +329,13 @@ public class AlignmentView * char * @return Object[] { SequenceI[], ColumnSelection} */ - public Object[] getAlignmentAndColumnSelection(char gapCharacter) + public Object[] getAlignmentAndHiddenColumns(char gapCharacter) { - ColumnSelection colsel = new ColumnSelection(); + HiddenColumns hidden = new HiddenColumns(); - return new Object[] - { - SeqCigar.createAlignmentSequences(sequences, gapCharacter, colsel, - contigs), colsel }; + return new Object[] { SeqCigar.createAlignmentSequences(sequences, + gapCharacter, hidden, contigs), + hidden }; } /** @@ -331,8 +368,8 @@ public class AlignmentView * - true if vcal is alignment of the visible regions of the view * (e.g. as returned from getVisibleAlignment) */ - private void addPrunedGroupsInOrder(AlignmentI vcal, int gstart, - int gend, boolean viscontigs) + private void addPrunedGroupsInOrder(AlignmentI vcal, int gstart, int gend, + boolean viscontigs) { boolean r = false; if (gstart > -1 && gstart <= gend) @@ -352,7 +389,7 @@ public class AlignmentView SequenceGroup[] nsg = new SequenceGroup[nvg]; for (int g = 0; g < nvg; g++) { - SequenceGroup sg = ((ScGroup) scGroups.elementAt(g)).sg; + SequenceGroup sg = scGroups.get(g).sg; if (r) { if (sg.getStartRes() > gend || sg.getEndRes() < gstart) @@ -402,8 +439,8 @@ public class AlignmentView for (int h = 0; h < contigs.length; h += 3) { { - prune.addShift(p + contigs[h + 1], contigs[h + 2] - - contigs[h + 1]); + prune.addShift(p + contigs[h + 1], + contigs[h + 2] - contigs[h + 1]); } p = contigs[h + 1] + contigs[h + 2]; } @@ -438,7 +475,7 @@ public class AlignmentView for (int g = 0; g < nvg; g++) { if (nsg[g] != null - && sequences[nsq].isMemberOf(scGroups.elementAt(g))) + && sequences[nsq].isMemberOf(scGroups.get(g))) { nsg[g].addSequence(aln[nsq], false); } @@ -462,6 +499,7 @@ public class AlignmentView * alignment. * * @param c + * gap character to use to recreate the alignment * @return */ private SequenceI[] getVisibleSeqs(char c) @@ -469,13 +507,9 @@ public class AlignmentView SequenceI[] aln = new SequenceI[sequences.length]; for (int i = 0, j = sequences.length; i < j; i++) { - aln[i] = sequences[i].getSeq('-'); - } - // Remove hidden regions from sequence objects. - String seqs[] = getSequenceStrings('-'); - for (int i = 0, j = aln.length; i < j; i++) - { - aln[i].setSequence(seqs[i]); + aln[i] = sequences[i].getSeq(c); + // Remove hidden regions from sequence + aln[i].setSequence(getASequenceString(c, i)); } return aln; } @@ -511,8 +545,38 @@ public class AlignmentView } /** + * build a string excluding hidden regions from a particular sequence in the + * view + * + * @param c + * @param n + * @return + */ + private String getASequenceString(char c, int n) + { + String sqn; + String fullseq = sequences[n].getSequenceString(c); + if (contigs != null) + { + sqn = ""; + int p = 0; + for (int h = 0; h < contigs.length; h += 3) + { + sqn += fullseq.substring(p, contigs[h + 1]); + p = contigs[h + 1] + contigs[h + 2]; + } + sqn += fullseq.substring(p); + } + else + { + sqn = fullseq; + } + return sqn; + } + + /** * get an array of visible sequence strings for a view on an alignment using - * the given gap character + * the given gap character uses getASequenceString * * @param c * char @@ -523,22 +587,7 @@ public class AlignmentView String[] seqs = new String[sequences.length]; for (int n = 0; n < sequences.length; n++) { - String fullseq = sequences[n].getSequenceString(c); - if (contigs != null) - { - seqs[n] = ""; - int p = 0; - for (int h = 0; h < contigs.length; h += 3) - { - seqs[n] += fullseq.substring(p, contigs[h + 1]); - p = contigs[h + 1] + contigs[h + 2]; - } - seqs[n] += fullseq.substring(p); - } - else - { - seqs[n] = fullseq; - } + seqs[n] = getASequenceString(c, n); } return seqs; } @@ -601,8 +650,8 @@ public class AlignmentView SequenceI mseq[] = new SequenceI[sequences.length]; for (int s = 0; s < mseq.length; s++) { - mseq[s] = sequences[s].getSeq(gapCharacter).getSubSequence( - start, contigs[contig + 1]); + mseq[s] = sequences[s].getSeq(gapCharacter) + .getSubSequence(start, contigs[contig + 1]); } smsa[j] = mseq; j++; @@ -648,7 +697,8 @@ public class AlignmentView { if (sequences == null || width <= 0) { - throw new Error("empty view cannot be updated."); + throw new Error(MessageManager + .getString("error.empty_view_cannot_be_updated")); } if (nvismsa == null) { @@ -658,7 +708,8 @@ public class AlignmentView if (contigs != null && contigs.length > 0) { SequenceI[] alignment = new SequenceI[sequences.length]; - ColumnSelection columnselection = new ColumnSelection(); + // ColumnSelection columnselection = new ColumnSelection(); + HiddenColumns hidden = new HiddenColumns(); if (contigs != null && contigs.length > 0) { int start = 0; @@ -678,11 +729,13 @@ public class AlignmentView j++; if (mseq.length != sequences.length) { - throw new Error( - "Mismatch between number of sequences in block " - + j + " (" + mseq.length - + ") and the original view (" - + sequences.length + ")"); + throw new Error(MessageManager.formatMessage( + "error.mismatch_between_number_of_sequences_in_block", + new String[] + { Integer.valueOf(j).toString(), + Integer.valueOf(mseq.length).toString(), + Integer.valueOf(sequences.length) + .toString() })); } swidth = mseq[0].getLength(); // JBPNote: could ensure padded // here. @@ -694,9 +747,9 @@ public class AlignmentView } else { - alignment[s].setSequence(alignment[s] - .getSequenceAsString() - + mseq[s].getSequenceAsString()); + alignment[s] + .setSequence(alignment[s].getSequenceAsString() + + mseq[s].getSequenceAsString()); if (mseq[s].getStart() <= mseq[s].getEnd()) { alignment[s].setEnd(mseq[s].getEnd()); @@ -728,9 +781,9 @@ public class AlignmentView } else { - alignment[s].setSequence(alignment[s] - .getSequenceAsString() - + oseq.getSequenceAsString()); + alignment[s] + .setSequence(alignment[s].getSequenceAsString() + + oseq.getSequenceAsString()); if (oseq.getEnd() >= oseq.getStart()) { alignment[s].setEnd(oseq.getEnd()); @@ -765,8 +818,7 @@ public class AlignmentView } } // mark hidden segment as hidden in the new alignment - columnselection.hideColumns(nwidth, nwidth + contigs[contig + 2] - - 1); + hidden.hideColumns(nwidth, nwidth + contigs[contig + 2] - 1); nwidth += contigs[contig + 2]; } // Do final segment - if it exists @@ -821,9 +873,9 @@ public class AlignmentView } else { - alignment[s].setSequence(alignment[s] - .getSequenceAsString() - + oseq.getSequenceAsString()); + alignment[s] + .setSequence(alignment[s].getSequenceAsString() + + oseq.getSequenceAsString()); if (oseq.getEnd() >= oseq.getStart()) { alignment[s].setEnd(oseq.getEnd()); @@ -835,31 +887,31 @@ public class AlignmentView else { // place gaps. - throw new Error("Padding not yet implemented."); + throw new Error(MessageManager + .getString("error.padding_not_yet_implemented")); } } } } } - return new Object[] - { alignment, columnselection }; + return new Object[] { alignment, hidden }; } else { if (nvismsa.length != 1) { - throw new Error( - "Mismatch between visible blocks to update and number of contigs in view (contigs=0,blocks=" - + nvismsa.length); + throw new Error(MessageManager.formatMessage( + "error.mismatch_between_visible_blocks_to_update_and_number_of_contigs_in_view", + new String[] + { Integer.valueOf(nvismsa.length).toString() })); } if (nvismsa[0] != null) { - return new Object[] - { nvismsa[0], new ColumnSelection() }; + return new Object[] { nvismsa[0], new HiddenColumns() }; } else { - return getAlignmentAndColumnSelection(gapCharacter); + return getAlignmentAndHiddenColumns(gapCharacter); } } } @@ -909,15 +961,14 @@ public class AlignmentView if (start < fwidth) { viscontigs[nvis] = start; - viscontigs[nvis + 1] = fwidth; // end is inclusive + viscontigs[nvis + 1] = fwidth - 1; // end is inclusive nvis += 2; } return viscontigs; } else { - return new int[] - { 0, width }; + return new int[] { 0, width - 1 }; } } @@ -1040,17 +1091,17 @@ public class AlignmentView + " groups defined on the view."); for (int g = 0; g < view.scGroups.size(); g++) { - ScGroup sgr = (ScGroup) view.scGroups.elementAt(g); + ScGroup sgr = view.scGroups.get(g); os.println("Group " + g + ": Name = " + sgr.sg.getName() + " Contains " + sgr.seqs.size() + " Seqs."); os.println("This group runs from " + sgr.sg.getStartRes() + " to " + sgr.sg.getEndRes()); for (int s = 0; s < sgr.seqs.size(); s++) { - if (!((SeqCigar) sgr.seqs.elementAt(s)).isMemberOf(sgr)) + // JBPnote this should be a unit test for ScGroup + if (!sgr.seqs.get(s).isMemberOf(sgr)) { - os.println("** WARNING: sequence " - + ((SeqCigar) sgr.seqs.elementAt(s)).toString() + os.println("** WARNING: sequence " + sgr.seqs.get(s).toString() + " is not marked as member of group."); } } @@ -1075,113 +1126,114 @@ public class AlignmentView } public static void testSelectionViews(AlignmentI alignment, - ColumnSelection csel, SequenceGroup selection) + HiddenColumns hidden, SequenceGroup selection) { - System.out.println("Testing standard view creation:\n"); + jalview.bin.Console.outPrintln("Testing standard view creation:\n"); AlignmentView view = null; try { - System.out - .println("View with no hidden columns, no limit to selection, no groups to be collected:"); - view = new AlignmentView(alignment, csel, selection, false, false, + jalview.bin.Console.outPrintln( + "View with no hidden columns, no limit to selection, no groups to be collected:"); + view = new AlignmentView(alignment, hidden, selection, false, false, false); summariseAlignmentView(view, System.out); } catch (Exception e) { e.printStackTrace(); - System.err - .println("Failed to generate alignment with selection but no groups marked."); + jalview.bin.Console.errPrintln( + "Failed to generate alignment with selection but no groups marked."); } try { - System.out - .println("View with no hidden columns, no limit to selection, and all groups to be collected:"); - view = new AlignmentView(alignment, csel, selection, false, false, + jalview.bin.Console.outPrintln( + "View with no hidden columns, no limit to selection, and all groups to be collected:"); + view = new AlignmentView(alignment, hidden, selection, false, false, true); summariseAlignmentView(view, System.out); } catch (Exception e) { e.printStackTrace(); - System.err - .println("Failed to generate alignment with selection marked but no groups marked."); + jalview.bin.Console.errPrintln( + "Failed to generate alignment with selection marked but no groups marked."); } try { - System.out - .println("View with no hidden columns, limited to selection and no groups to be collected:"); - view = new AlignmentView(alignment, csel, selection, false, true, + jalview.bin.Console.outPrintln( + "View with no hidden columns, limited to selection and no groups to be collected:"); + view = new AlignmentView(alignment, hidden, selection, false, true, false); summariseAlignmentView(view, System.out); } catch (Exception e) { e.printStackTrace(); - System.err - .println("Failed to generate alignment with selection restricted but no groups marked."); + jalview.bin.Console.errPrintln( + "Failed to generate alignment with selection restricted but no groups marked."); } try { - System.out - .println("View with no hidden columns, limited to selection, and all groups to be collected:"); - view = new AlignmentView(alignment, csel, selection, false, true, + jalview.bin.Console.outPrintln( + "View with no hidden columns, limited to selection, and all groups to be collected:"); + view = new AlignmentView(alignment, hidden, selection, false, true, true); summariseAlignmentView(view, System.out); } catch (Exception e) { e.printStackTrace(); - System.err - .println("Failed to generate alignment with selection restricted and groups marked."); + jalview.bin.Console.errPrintln( + "Failed to generate alignment with selection restricted and groups marked."); } try { - System.out - .println("View *with* hidden columns, no limit to selection, no groups to be collected:"); - view = new AlignmentView(alignment, csel, selection, true, false, + jalview.bin.Console.outPrintln( + "View *with* hidden columns, no limit to selection, no groups to be collected:"); + view = new AlignmentView(alignment, hidden, selection, true, false, false); summariseAlignmentView(view, System.out); } catch (Exception e) { e.printStackTrace(); - System.err - .println("Failed to generate alignment with selection but no groups marked."); + jalview.bin.Console.errPrintln( + "Failed to generate alignment with selection but no groups marked."); } try { - System.out - .println("View *with* hidden columns, no limit to selection, and all groups to be collected:"); - view = new AlignmentView(alignment, csel, selection, true, false, + jalview.bin.Console.outPrintln( + "View *with* hidden columns, no limit to selection, and all groups to be collected:"); + view = new AlignmentView(alignment, hidden, selection, true, false, true); summariseAlignmentView(view, System.out); } catch (Exception e) { e.printStackTrace(); - System.err - .println("Failed to generate alignment with selection marked but no groups marked."); + jalview.bin.Console.errPrintln( + "Failed to generate alignment with selection marked but no groups marked."); } try { - System.out - .println("View *with* hidden columns, limited to selection and no groups to be collected:"); - view = new AlignmentView(alignment, csel, selection, true, true, + jalview.bin.Console.outPrintln( + "View *with* hidden columns, limited to selection and no groups to be collected:"); + view = new AlignmentView(alignment, hidden, selection, true, true, false); summariseAlignmentView(view, System.out); } catch (Exception e) { e.printStackTrace(); - System.err - .println("Failed to generate alignment with selection restricted but no groups marked."); + jalview.bin.Console.errPrintln( + "Failed to generate alignment with selection restricted but no groups marked."); } try { - System.out - .println("View *with* hidden columns, limited to selection, and all groups to be collected:"); - view = new AlignmentView(alignment, csel, selection, true, true, true); + jalview.bin.Console.outPrintln( + "View *with* hidden columns, limited to selection, and all groups to be collected:"); + view = new AlignmentView(alignment, hidden, selection, true, true, + true); summariseAlignmentView(view, System.out); } catch (Exception e) { e.printStackTrace(); - System.err - .println("Failed to generate alignment with selection restricted and groups marked."); + jalview.bin.Console.errPrintln( + "Failed to generate alignment with selection restricted and groups marked."); } }