X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fviewmodel%2FAlignmentViewport.java;h=2881e8150261b33d066158fd6399ed0c6b270bb2;hb=8a0c21a00b4ac6925f6b6a04d1ea43cff44eea50;hp=354775780d23fbe502302f726c265486d3555dcf;hpb=84724ad7b25f65eb6009f70d9b4cb89fc6796622;p=jalview.git diff --git a/src/jalview/viewmodel/AlignmentViewport.java b/src/jalview/viewmodel/AlignmentViewport.java index 3547757..2881e81 100644 --- a/src/jalview/viewmodel/AlignmentViewport.java +++ b/src/jalview/viewmodel/AlignmentViewport.java @@ -20,17 +20,6 @@ */ package jalview.viewmodel; -import java.awt.Color; -import java.beans.PropertyChangeSupport; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.BitSet; -import java.util.Deque; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.List; -import java.util.Map; - import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder; import jalview.analysis.Conservation; import jalview.api.AlignCalcManagerI; @@ -46,6 +35,7 @@ import jalview.datamodel.AlignmentView; import jalview.datamodel.Annotation; import jalview.datamodel.CigarArray; import jalview.datamodel.ColumnSelection; +import jalview.datamodel.HiddenColumns; import jalview.datamodel.HiddenSequences; import jalview.datamodel.ProfilesI; import jalview.datamodel.SearchResultsI; @@ -62,12 +52,24 @@ import jalview.structure.VamsasSource; import jalview.util.Comparison; import jalview.util.MapList; import jalview.util.MappingUtils; +import jalview.util.MessageManager; import jalview.viewmodel.styles.ViewStyle; import jalview.workers.AlignCalcManager; import jalview.workers.ComplementConsensusThread; import jalview.workers.ConsensusThread; import jalview.workers.StrucConsensusThread; +import java.awt.Color; +import java.beans.PropertyChangeSupport; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.BitSet; +import java.util.Deque; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.List; +import java.util.Map; + /** * base class holding visualization and analysis attributes and common logic for * an active alignment view displayed in the GUI @@ -78,7 +80,7 @@ import jalview.workers.StrucConsensusThread; public abstract class AlignmentViewport implements AlignViewportI, CommandListener, VamsasSource { - protected ViewportRanges ranges; + final protected ViewportRanges ranges; protected ViewStyleI viewStyle = new ViewStyle(); @@ -90,9 +92,20 @@ public abstract class AlignmentViewport implements AlignViewportI, FeaturesDisplayedI featuresDisplayed = null; - protected Deque historyList = new ArrayDeque(); + protected Deque historyList = new ArrayDeque<>(); + + protected Deque redoList = new ArrayDeque<>(); + + /** + * alignment displayed in the viewport. Please use get/setter + */ + protected AlignmentI alignment; - protected Deque redoList = new ArrayDeque(); + public AlignmentViewport(AlignmentI al) + { + setAlignment(al); + ranges = new ViewportRanges(al); + } /** * @param name @@ -392,6 +405,7 @@ public abstract class AlignmentViewport implements AlignViewportI, public void setWrapAlignment(boolean state) { viewStyle.setWrapAlignment(state); + ranges.setWrappedMode(state); } /** @@ -554,10 +568,7 @@ public abstract class AlignmentViewport implements AlignViewportI, viewStyle.setSeqNameItalics(default1); } - /** - * alignment displayed in the viewport. Please use get/setter - */ - protected AlignmentI alignment; + @Override public AlignmentI getAlignment() @@ -599,7 +610,7 @@ public abstract class AlignmentViewport implements AlignViewportI, protected boolean ignoreGapsInConsensusCalculation = false; - protected ResidueShaderI residueShading; + protected ResidueShaderI residueShading = new ResidueShader(); @Override public void setGlobalColourScheme(ColourSchemeI cs) @@ -632,6 +643,11 @@ public abstract class AlignmentViewport implements AlignViewportI, { residueShading.setConservation(hconservation); } + /* + * reset conservation flag in case just set to false if + * Conservation was null (calculation still in progress) + */ + residueShading.setConservationApplied(getConservationSelected()); residueShading.alignmentChanged(alignment, hiddenRepSequences); } @@ -823,7 +839,7 @@ public abstract class AlignmentViewport implements AlignViewportI, public void updateConsensus(final AlignmentViewPanel ap) { // see note in mantis : issue number 8585 - if ((consensus == null || gapcounts == null) || !autoCalculateConsensus) + if (consensus == null || !autoCalculateConsensus) { return; } @@ -1100,9 +1116,9 @@ public abstract class AlignmentViewport implements AlignViewportI, } } - public void setHiddenColumns(ColumnSelection colsel) + public void setHiddenColumns(HiddenColumns hidden) { - this.colSel = colsel; + this.alignment.setHiddenColumns(hidden); } @Override @@ -1149,7 +1165,8 @@ public abstract class AlignmentViewport implements AlignViewportI, @Override public boolean hasHiddenColumns() { - return colSel != null && colSel.hasHiddenColumns(); + return alignment.getHiddenColumns() != null + && alignment.getHiddenColumns().hasHiddenColumns(); } public void updateHiddenColumns() @@ -1284,7 +1301,9 @@ public abstract class AlignmentViewport implements AlignViewportI, protected boolean showConsensus = true; - private Map sequenceColours = new HashMap(); + protected boolean showOccupancy = true; + + private Map sequenceColours = new HashMap<>(); protected SequenceAnnotationOrder sortAnnotationsBy = null; @@ -1344,7 +1363,7 @@ public abstract class AlignmentViewport implements AlignViewportI, return; } - colSel.hideSelectedColumns(); + colSel.hideSelectedColumns(alignment); setSelectionGroup(null); isColSelChanged(true); } @@ -1353,30 +1372,33 @@ public abstract class AlignmentViewport implements AlignViewportI, { if (start == end) { - colSel.hideColumns(start); + colSel.hideSelectedColumns(start, alignment.getHiddenColumns()); } else { - colSel.hideColumns(start, end); + alignment.getHiddenColumns().hideColumns(start, end); } isColSelChanged(true); } public void showColumn(int col) { - colSel.revealHiddenColumns(col); + alignment.getHiddenColumns().revealHiddenColumns(col, colSel); isColSelChanged(true); } public void showAllHiddenColumns() { - colSel.revealAllHiddenColumns(); + alignment.getHiddenColumns().revealAllHiddenColumns(colSel); isColSelChanged(true); } // common hide/show seq stuff public void showAllHiddenSeqs() { + int startSeq = ranges.getStartSeq(); + int endSeq = ranges.getEndSeq(); + if (alignment.getHiddenSequences().getSize() > 0) { if (selectionGroup == null) @@ -1394,6 +1416,8 @@ public abstract class AlignmentViewport implements AlignViewportI, hiddenRepSequences = null; + ranges.setStartEndSeq(startSeq, endSeq + tmp.size()); + firePropertyChange("alignment", null, alignment.getSequences()); // used to set hasHiddenRows/hiddenRepSequences here, after the property // changed event @@ -1403,6 +1427,9 @@ public abstract class AlignmentViewport implements AlignViewportI, public void showSequence(int index) { + int startSeq = ranges.getStartSeq(); + int endSeq = ranges.getEndSeq(); + List tmp = alignment.getHiddenSequences().showSequence( index, hiddenRepSequences); if (tmp.size() > 0) @@ -1418,6 +1445,9 @@ public abstract class AlignmentViewport implements AlignViewportI, selectionGroup.addSequence(seq, false); setSequenceAnnotationsVisible(seq, true); } + + ranges.setStartEndSeq(startSeq, endSeq + tmp.size()); + firePropertyChange("alignment", null, alignment.getSequences()); sendSelection(); } @@ -1439,6 +1469,11 @@ public abstract class AlignmentViewport implements AlignViewportI, public void hideSequence(SequenceI[] seq) { + /* + * cache offset to first visible sequence + */ + int startSeq = ranges.getStartSeq(); + if (seq != null) { for (int i = 0; i < seq.length; i++) @@ -1446,6 +1481,7 @@ public abstract class AlignmentViewport implements AlignViewportI, alignment.getHiddenSequences().hideSequence(seq[i]); setSequenceAnnotationsVisible(seq[i], false); } + ranges.setStartSeq(startSeq); firePropertyChange("alignment", null, alignment.getSequences()); } } @@ -1514,7 +1550,7 @@ public abstract class AlignmentViewport implements AlignViewportI, if (hiddenRepSequences == null) { - hiddenRepSequences = new Hashtable(); + hiddenRepSequences = new Hashtable<>(); } hiddenRepSequences.put(repSequence, sg); @@ -1592,7 +1628,7 @@ public abstract class AlignmentViewport implements AlignViewportI, @Override public void invertColumnSelection() { - colSel.invertColumnSelection(0, alignment.getWidth()); + colSel.invertColumnSelection(0, alignment.getWidth(), alignment); } @Override @@ -1640,7 +1676,7 @@ public abstract class AlignmentViewport implements AlignViewportI, @Override public CigarArray getViewAsCigars(boolean selectedRegionOnly) { - return new CigarArray(alignment, colSel, + return new CigarArray(alignment, alignment.getHiddenColumns(), (selectedRegionOnly ? selectionGroup : null)); } @@ -1655,8 +1691,10 @@ public abstract class AlignmentViewport implements AlignViewportI, public jalview.datamodel.AlignmentView getAlignmentView( boolean selectedOnly, boolean markGroups) { - return new AlignmentView(alignment, colSel, selectionGroup, - colSel != null && colSel.hasHiddenColumns(), selectedOnly, + return new AlignmentView(alignment, alignment.getHiddenColumns(), + selectionGroup, alignment.getHiddenColumns() != null + && alignment.getHiddenColumns().hasHiddenColumns(), + selectedOnly, markGroups); } @@ -1700,9 +1738,11 @@ public abstract class AlignmentViewport implements AlignViewportI, } selection = new String[iSize]; - if (colSel != null && colSel.hasHiddenColumns()) + if (alignment.getHiddenColumns() != null + && alignment.getHiddenColumns().hasHiddenColumns()) { - selection = colSel.getVisibleSequenceStrings(start, end, seqs); + selection = alignment.getHiddenColumns().getVisibleSequenceStrings( + start, end, seqs); } else { @@ -1718,20 +1758,21 @@ public abstract class AlignmentViewport implements AlignViewportI, @Override public List getVisibleRegionBoundaries(int min, int max) { - ArrayList regions = new ArrayList(); + ArrayList regions = new ArrayList<>(); int start = min; int end = max; do { - if (colSel != null && colSel.hasHiddenColumns()) + HiddenColumns hidden = alignment.getHiddenColumns(); + if (hidden != null && hidden.hasHiddenColumns()) { if (start == 0) { - start = colSel.adjustForHiddenColumns(start); + start = hidden.adjustForHiddenColumns(start); } - end = colSel.getHiddenBoundaryRight(start); + end = hidden.getHiddenBoundaryRight(start); if (start == end) { end = max; @@ -1744,10 +1785,10 @@ public abstract class AlignmentViewport implements AlignViewportI, regions.add(new int[] { start, end }); - if (colSel != null && colSel.hasHiddenColumns()) + if (hidden != null && hidden.hasHiddenColumns()) { - start = colSel.adjustForHiddenColumns(end); - start = colSel.getHiddenBoundaryLeft(start) + 1; + start = hidden.adjustForHiddenColumns(end); + start = hidden.getHiddenBoundaryLeft(start) + 1; } } while (end < max); @@ -1760,7 +1801,7 @@ public abstract class AlignmentViewport implements AlignViewportI, public List getVisibleAlignmentAnnotation( boolean selectedOnly) { - ArrayList ala = new ArrayList(); + ArrayList ala = new ArrayList<>(); AlignmentAnnotation[] aa; if ((aa = alignment.getAlignmentAnnotation()) != null) { @@ -1769,12 +1810,13 @@ public abstract class AlignmentViewport implements AlignViewportI, AlignmentAnnotation clone = new AlignmentAnnotation(annot); if (selectedOnly && selectionGroup != null) { - colSel.makeVisibleAnnotation(selectionGroup.getStartRes(), + alignment.getHiddenColumns().makeVisibleAnnotation( + selectionGroup.getStartRes(), selectionGroup.getEndRes(), clone); } else { - colSel.makeVisibleAnnotation(clone); + alignment.getHiddenColumns().makeVisibleAnnotation(clone); } ala.add(clone); } @@ -1890,24 +1932,21 @@ public abstract class AlignmentViewport implements AlignViewportI, { initRNAStructure(); } - consensus = new AlignmentAnnotation("Consensus", "PID", + consensus = new AlignmentAnnotation("Consensus", + MessageManager.getString("label.consensus_descr"), new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH); initConsensus(consensus); - gapcounts = new AlignmentAnnotation("Occupancy", - "Number of aligned positions", - new Annotation[1], 0f, alignment.getHeight(), - AlignmentAnnotation.BAR_GRAPH); - initGapCounts(gapcounts); + initGapCounts(); initComplementConsensus(); } } /** - * If this is a protein alignment and there are mappings to cDNA, add the cDNA - * consensus annotation. + * If this is a protein alignment and there are mappings to cDNA, adds the + * cDNA consensus annotation and returns true, else returns false. */ - public void initComplementConsensus() + public boolean initComplementConsensus() { if (!alignment.isNucleotide()) { @@ -1931,12 +1970,16 @@ public abstract class AlignmentViewport implements AlignViewportI, if (doConsensus) { complementConsensus = new AlignmentAnnotation("cDNA Consensus", - "PID for cDNA", new Annotation[1], 0f, 100f, + MessageManager + .getString("label.complement_consensus_descr"), + new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH); initConsensus(complementConsensus); + return true; } } } + return false; } private void initConsensus(AlignmentAnnotation aa) @@ -1952,15 +1995,20 @@ public abstract class AlignmentViewport implements AlignViewportI, // these should be extracted from the view model - style and settings for // derived annotation - private void initGapCounts(AlignmentAnnotation counts) + private void initGapCounts() { - counts.hasText = false; - counts.autoCalculated = true; - counts.graph = AlignmentAnnotation.BAR_GRAPH; - - if (showConsensus) + if (showOccupancy) { - alignment.addAnnotation(counts); + gapcounts = new AlignmentAnnotation("Occupancy", + MessageManager.getString("label.occupancy_descr"), + new Annotation[1], 0f, + alignment.getHeight(), AlignmentAnnotation.BAR_GRAPH); + gapcounts.hasText = true; + gapcounts.autoCalculated = true; + gapcounts.scaleColLabel = true; + gapcounts.graph = AlignmentAnnotation.BAR_GRAPH; + + alignment.addAnnotation(gapcounts); } } @@ -1971,8 +2019,8 @@ public abstract class AlignmentViewport implements AlignViewportI, if (conservation == null) { conservation = new AlignmentAnnotation("Conservation", - "Conservation of total alignment less than " - + getConsPercGaps() + "% gaps", new Annotation[1], + MessageManager.formatMessage("label.conservation_descr", + getConsPercGaps()), new Annotation[1], 0f, 11f, AlignmentAnnotation.BAR_GRAPH); conservation.hasText = true; conservation.autoCalculated = true; @@ -1988,7 +2036,7 @@ public abstract class AlignmentViewport implements AlignViewportI, if (quality == null) { quality = new AlignmentAnnotation("Quality", - "Alignment Quality based on Blosum62 scores", + MessageManager.getString("label.quality_descr"), new Annotation[1], 0f, 11f, AlignmentAnnotation.BAR_GRAPH); quality.hasText = true; quality.autoCalculated = true; @@ -2001,7 +2049,8 @@ public abstract class AlignmentViewport implements AlignViewportI, { if (alignment.hasRNAStructure() && strucConsensus == null) { - strucConsensus = new AlignmentAnnotation("StrucConsensus", "PID", + strucConsensus = new AlignmentAnnotation("StrucConsensus", + MessageManager.getString("label.strucconsensus_descr"), new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH); strucConsensus.hasText = true; strucConsensus.autoCalculated = true; @@ -2106,7 +2155,7 @@ public abstract class AlignmentViewport implements AlignViewportI, // intersect alignment annotation with alignment groups AlignmentAnnotation[] aan = alignment.getAlignmentAnnotation(); - List oldrfs = new ArrayList(); + List oldrfs = new ArrayList<>(); if (aan != null) { for (int an = 0; an < aan.length; an++) @@ -2648,6 +2697,18 @@ public abstract class AlignmentViewport implements AlignViewportI, viewStyle.setScaleProteinAsCdna(b); } + @Override + public boolean isProteinFontAsCdna() + { + return viewStyle.isProteinFontAsCdna(); + } + + @Override + public void setProteinFontAsCdna(boolean b) + { + viewStyle.setProteinFontAsCdna(b); + } + /** * @return true if view should scroll to show the highlighted region of a * sequence @@ -2807,8 +2868,7 @@ public abstract class AlignmentViewport implements AlignViewportI, selectionIsDefinedGroup = gps.contains(selectionGroup); } } - return selectionGroup.getContext() == alignment - || selectionIsDefinedGroup; + return selectionGroup.isDefined() || selectionIsDefinedGroup; } /** @@ -2833,4 +2893,45 @@ public abstract class AlignmentViewport implements AlignViewportI, { return searchResults; } + + /** + * get the consensus sequence as displayed under the PID consensus annotation + * row. + * + * @return consensus sequence as a new sequence object + */ + public SequenceI getConsensusSeq() + { + if (consensus == null) + { + updateConsensus(null); + } + if (consensus == null) + { + return null; + } + StringBuffer seqs = new StringBuffer(); + for (int i = 0; i < consensus.annotations.length; i++) + { + Annotation annotation = consensus.annotations[i]; + if (annotation != null) + { + String description = annotation.description; + if (description != null && description.startsWith("[")) + { + // consensus is a tie - just pick the first one + seqs.append(description.charAt(1)); + } + else + { + seqs.append(annotation.displayCharacter); + } + } + } + + SequenceI sq = new Sequence("Consensus", seqs.toString()); + sq.setDescription("Percentage Identity Consensus " + + ((ignoreGapsInConsensusCalculation) ? " without gaps" : "")); + return sq; + } }