X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fviewmodel%2FAlignmentViewport.java;h=0803773cc6e2008e53a7bd98269b869a23cc02c4;hb=09d9063e70931a6cb75d16b230f5cd0665f0f340;hp=eab4aa569d268ec3985d904aab044d268448253c;hpb=048a384fa19ac37fbe2b63bbba139d5fa17107c5;p=jalview.git diff --git a/src/jalview/viewmodel/AlignmentViewport.java b/src/jalview/viewmodel/AlignmentViewport.java index eab4aa5..0803773 100644 --- a/src/jalview/viewmodel/AlignmentViewport.java +++ b/src/jalview/viewmodel/AlignmentViewport.java @@ -36,15 +36,17 @@ import jalview.datamodel.Annotation; import jalview.datamodel.CigarArray; import jalview.datamodel.ColumnSelection; import jalview.datamodel.HiddenSequences; -import jalview.datamodel.SearchResults; +import jalview.datamodel.ProfilesI; +import jalview.datamodel.SearchResultsI; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceCollectionI; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; import jalview.schemes.Blosum62ColourScheme; +import jalview.schemes.CollectionColourScheme; +import jalview.schemes.CollectionColourSchemeI; import jalview.schemes.ColourSchemeI; import jalview.schemes.PIDColourScheme; -import jalview.schemes.ResidueProperties; import jalview.structure.CommandListener; import jalview.structure.StructureSelectionManager; import jalview.structure.VamsasSource; @@ -58,6 +60,7 @@ 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; @@ -596,7 +599,7 @@ public abstract class AlignmentViewport implements AlignViewportI, protected boolean ignoreGapsInConsensusCalculation = false; - protected ColourSchemeI globalColourScheme = null; + protected CollectionColourScheme globalColourScheme; @Override public void setGlobalColourScheme(ColourSchemeI cs) @@ -608,28 +611,39 @@ public abstract class AlignmentViewport implements AlignViewportI, // - means that caller decides if they want to just modify state and defer // calculation till later or to do all calculations in thread. // via changecolour - globalColourScheme = cs; + + /* + * only instantiate colour scheme once, thereafter update it + */ + if (globalColourScheme == null) + { + globalColourScheme = new CollectionColourScheme(); + } + globalColourScheme.setColourScheme(cs); + boolean recalc = false; if (cs != null) { - cs.setConservationApplied(recalc = getConservationSelected()); + recalc = getConservationSelected(); if (getAbovePIDThreshold() || cs instanceof PIDColourScheme || cs instanceof Blosum62ColourScheme) { recalc = true; - cs.setThreshold(viewStyle.getThreshold(), + globalColourScheme.setThreshold(viewStyle.getThreshold(), ignoreGapsInConsensusCalculation); } else { - cs.setThreshold(0, ignoreGapsInConsensusCalculation); + globalColourScheme + .setThreshold(0, ignoreGapsInConsensusCalculation); } if (recalc) { - cs.setConsensus(hconsensus); - cs.setConservation(hconservation); + globalColourScheme.setConsensus(hconsensus); + globalColourScheme.setConservation(hconservation); } - cs.alignmentChanged(alignment, hiddenRepSequences); + globalColourScheme.setConservationApplied(getConservationSelected()); + globalColourScheme.alignmentChanged(alignment, hiddenRepSequences); } if (getColourAppliesToAllGroups()) { @@ -637,31 +651,33 @@ public abstract class AlignmentViewport implements AlignViewportI, { if (cs == null) { - sg.cs = null; + sg.setColourScheme(null); continue; } - sg.cs = cs.applyTo(sg, getHiddenRepSequences()); + CollectionColourScheme groupColour = new CollectionColourScheme(cs.getInstance(sg, + getHiddenRepSequences())); + sg.setGroupColourScheme(groupColour); sg.setConsPercGaps(ConsPercGaps); if (getAbovePIDThreshold() || cs instanceof PIDColourScheme || cs instanceof Blosum62ColourScheme) { - sg.cs.setThreshold(viewStyle.getThreshold(), + groupColour.setThreshold(viewStyle.getThreshold(), isIgnoreGapsConsensus()); recalc = true; } else { - sg.cs.setThreshold(0, isIgnoreGapsConsensus()); + groupColour.setThreshold(0, isIgnoreGapsConsensus()); } if (getConservationSelected()) { - sg.cs.setConservationApplied(true); + groupColour.setConservationApplied(true); recalc = true; } else { - sg.cs.setConservation(null); + groupColour.setConservation(null); // sg.cs.setThreshold(0, getIgnoreGapsConsensus()); } if (recalc) @@ -670,7 +686,7 @@ public abstract class AlignmentViewport implements AlignViewportI, } else { - sg.cs.alignmentChanged(sg, hiddenRepSequences); + groupColour.alignmentChanged(sg, hiddenRepSequences); } } } @@ -679,6 +695,13 @@ public abstract class AlignmentViewport implements AlignViewportI, @Override public ColourSchemeI getGlobalColourScheme() { + return globalColourScheme == null ? null : globalColourScheme + .getColourScheme(); + } + + @Override + public CollectionColourSchemeI getViewportColourScheme() + { return globalColourScheme; } @@ -699,7 +722,7 @@ public abstract class AlignmentViewport implements AlignViewportI, /** * results of alignment consensus analysis for visible portion of view */ - protected Hashtable[] hconsensus = null; + protected ProfilesI hconsensus = null; /** * results of cDNA complement consensus visible portion of view @@ -733,7 +756,7 @@ public abstract class AlignmentViewport implements AlignViewportI, } @Override - public void setSequenceConsensusHash(Hashtable[] hconsensus) + public void setSequenceConsensusHash(ProfilesI hconsensus) { this.hconsensus = hconsensus; } @@ -745,7 +768,7 @@ public abstract class AlignmentViewport implements AlignViewportI, } @Override - public Hashtable[] getSequenceConsensusHash() + public ProfilesI getSequenceConsensusHash() { return hconsensus; } @@ -807,7 +830,8 @@ public abstract class AlignmentViewport implements AlignViewportI, public void updateConservation(final AlignmentViewPanel ap) { // see note in mantis : issue number 8585 - if (alignment.isNucleotide() || conservation == null + if (alignment.isNucleotide() + || (conservation == null && quality == null) || !autoCalculateConsensus) { return; @@ -844,14 +868,22 @@ public abstract class AlignmentViewport implements AlignViewportI, && !al.getCodonFrames().isEmpty()) { /* - * fudge - check first mapping is protein-to-nucleotide + * fudge - check first for protein-to-nucleotide mappings * (we don't want to do this for protein-to-protein) */ - AlignedCodonFrame mapping = al.getCodonFrames().iterator().next(); - // TODO hold mapping type e.g. dna-to-protein in AlignedCodonFrame? - MapList[] mapLists = mapping.getdnaToProt(); - // mapLists can be empty if project load has not finished resolving seqs - if (mapLists.length > 0 && mapLists[0].getFromRatio() == 3) + boolean doConsensus = false; + for (AlignedCodonFrame mapping : al.getCodonFrames()) + { + // TODO hold mapping type e.g. dna-to-protein in AlignedCodonFrame? + MapList[] mapLists = mapping.getdnaToProt(); + // mapLists can be empty if project load has not finished resolving seqs + if (mapLists.length > 0 && mapLists[0].getFromRatio() == 3) + { + doConsensus = true; + break; + } + } + if (doConsensus) { if (calculator .getRegisteredWorkersOfClass(ComplementConsensusThread.class) == null) @@ -905,6 +937,37 @@ public abstract class AlignmentViewport implements AlignViewportI, return false; } + public void setAlignment(AlignmentI align) + { + this.alignment = align; + } + + /** + * Clean up references when this viewport is closed + */ + @Override + public void dispose() + { + /* + * defensively null out references to large objects in case + * this object is not garbage collected (as if!) + */ + consensus = null; + complementConsensus = null; + strucConsensus = null; + conservation = null; + quality = null; + groupConsensus = null; + groupConservation = null; + hconsensus = null; + hcomplementConsensus = null; + // colour scheme may hold reference to consensus + globalColourScheme = null; + // TODO remove listeners from changeSupport? + changeSupport = null; + setAlignment(null); + } + @Override public boolean isClosed() { @@ -1099,6 +1162,13 @@ public abstract class AlignmentViewport implements AlignViewportI, } @Override + public boolean hasSelectedColumns() + { + ColumnSelection columnSelection = getColumnSelection(); + return columnSelection != null && columnSelection.hasSelectedColumns(); + } + + @Override public boolean hasHiddenColumns() { return colSel != null && colSel.hasHiddenColumns(); @@ -1225,10 +1295,9 @@ public abstract class AlignmentViewport implements AlignViewportI, return ignoreGapsInConsensusCalculation; } - // / property change stuff - + // property change stuff // JBPNote Prolly only need this in the applet version. - private final java.beans.PropertyChangeSupport changeSupport = new java.beans.PropertyChangeSupport( + private PropertyChangeSupport changeSupport = new PropertyChangeSupport( this); protected boolean showConservation = true; @@ -1529,7 +1598,7 @@ public abstract class AlignmentViewport implements AlignViewportI, public boolean isHiddenRepSequence(SequenceI seq) { return (hiddenRepSequences != null && hiddenRepSequences - .containsKey(seq)); + .containsKey(seq)); } /** @@ -1811,7 +1880,7 @@ public abstract class AlignmentViewport implements AlignViewportI, */ void resetAllColourSchemes() { - ColourSchemeI cs = globalColourScheme; + CollectionColourScheme cs = globalColourScheme; if (cs != null) { cs.alignmentChanged(alignment, hiddenRepSequences); @@ -1820,8 +1889,8 @@ public abstract class AlignmentViewport implements AlignViewportI, if (cs.conservationApplied()) { cs.setConservation(Conservation.calculateConservation("All", - ResidueProperties.propHash, 3, alignment.getSequences(), 0, - alignment.getWidth(), false, getConsPercGaps(), false)); + alignment.getSequences(), 0, alignment.getWidth(), false, + getConsPercGaps(), false)); } } @@ -1872,12 +1941,20 @@ public abstract class AlignmentViewport implements AlignViewportI, .getCodonFrames(); if (codonMappings != null && !codonMappings.isEmpty()) { - // fudge: check mappings are not protein-to-protein - // TODO: nicer - AlignedCodonFrame mapping = codonMappings.iterator().next(); - MapList[] mapLists = mapping.getdnaToProt(); - // mapLists can be empty if project load has not finished resolving seqs - if (mapLists.length > 0 && mapLists[0].getFromRatio() == 3) + boolean doConsensus = false; + for (AlignedCodonFrame mapping : codonMappings) + { + // TODO hold mapping type e.g. dna-to-protein in AlignedCodonFrame? + MapList[] mapLists = mapping.getdnaToProt(); + // mapLists can be empty if project load has not finished resolving + // seqs + if (mapLists.length > 0 && mapLists[0].getFromRatio() == 3) + { + doConsensus = true; + break; + } + } + if (doConsensus) { complementConsensus = new AlignmentAnnotation("cDNA Consensus", "PID for cDNA", new Annotation[1], 0f, 100f, @@ -2662,7 +2739,7 @@ public abstract class AlignmentViewport implements AlignViewportI, * the SearchResults to add to * @return the offset (below top of visible region) of the matched sequence */ - protected int findComplementScrollTarget(SearchResults sr) + protected int findComplementScrollTarget(SearchResultsI sr) { final AlignViewportI complement = getCodingComplement(); if (complement == null || !complement.isFollowHighlight()) @@ -2700,6 +2777,7 @@ public abstract class AlignmentViewport implements AlignViewportI, * all gapped visible regions */ int lastSeq = alignment.getHeight() - 1; + List seqMappings = null; for (int seqNo = getStartSeq(); seqNo < lastSeq; seqNo++, seqOffset++) { sequence = getAlignment().getSequenceAt(seqNo); @@ -2711,15 +2789,16 @@ public abstract class AlignmentViewport implements AlignViewportI, { continue; } - List seqMappings = MappingUtils - .findMappingsForSequence(sequence, mappings); + seqMappings = MappingUtils + .findMappingsForSequenceAndOthers(sequence, mappings, + getCodingComplement().getAlignment().getSequences()); if (!seqMappings.isEmpty()) { break; } } - if (sequence == null) + if (sequence == null || seqMappings == null || seqMappings.isEmpty()) { /* * No ungapped mapped sequence in middle column - do nothing @@ -2727,7 +2806,7 @@ public abstract class AlignmentViewport implements AlignViewportI, return 0; } MappingUtils.addSearchResults(sr, sequence, - sequence.findPosition(middleColumn), mappings); + sequence.findPosition(middleColumn), seqMappings); return seqOffset; } @@ -2742,11 +2821,9 @@ public abstract class AlignmentViewport implements AlignViewportI, public void expandColSelection(SequenceGroup sg, boolean wholewidth) { int sgs, sge; - if (sg != null - && (sgs = sg.getStartRes()) >= 0 + if (sg != null && (sgs = sg.getStartRes()) >= 0 && sg.getStartRes() <= (sge = sg.getEndRes()) - && (colSel == null || colSel.getSelected() == null || colSel - .getSelected().size() == 0)) + && !this.hasSelectedColumns()) { if (!wholewidth && alignment.getWidth() == (1 + sge - sgs)) { @@ -2764,5 +2841,56 @@ public abstract class AlignmentViewport implements AlignViewportI, } } + /** + * hold status of current selection group - defined on alignment or not. + */ + private boolean selectionIsDefinedGroup = false; + + + @Override + public boolean isSelectionDefinedGroup() + { + if (selectionGroup == null) + { + return false; + } + if (isSelectionGroupChanged(true)) + { + selectionIsDefinedGroup = false; + List gps = alignment.getGroups(); + if (gps == null || gps.size() == 0) + { + selectionIsDefinedGroup = false; + } + else + { + selectionIsDefinedGroup = gps.contains(selectionGroup); + } + } + return selectionGroup.getContext() == alignment + || selectionIsDefinedGroup; + } + + /** + * null, or currently highlighted results on this view + */ + private SearchResultsI searchResults = null; + + @Override + public boolean hasSearchResults() + { + return searchResults != null; + } + + @Override + public void setSearchResults(SearchResultsI results) + { + searchResults = results; + } + @Override + public SearchResultsI getSearchResults() + { + return searchResults; + } }