X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fviewmodel%2FAlignmentViewport.java;h=01668a5bb5dc8eaf8af5cc900a77ce79d1ff91bd;hb=f2b03e9fecf41886ebf5f747fd4be02edf042bee;hp=7bbe67795eff08fbf675e9a273d825714b0ead13;hpb=cb98f8af1387172026ae298ead3ffb29aa04510c;p=jalview.git diff --git a/src/jalview/viewmodel/AlignmentViewport.java b/src/jalview/viewmodel/AlignmentViewport.java index 7bbe677..01668a5 100644 --- a/src/jalview/viewmodel/AlignmentViewport.java +++ b/src/jalview/viewmodel/AlignmentViewport.java @@ -25,6 +25,7 @@ import jalview.analysis.Conservation; import jalview.api.AlignCalcManagerI; import jalview.api.AlignViewportI; import jalview.api.AlignmentViewPanel; +import jalview.api.ColorI; import jalview.api.FeaturesDisplayedI; import jalview.api.ViewStyleI; import jalview.commands.CommandI; @@ -42,6 +43,7 @@ import jalview.datamodel.SequenceCollectionI; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; import jalview.schemes.Blosum62ColourScheme; +import jalview.schemes.Colour; import jalview.schemes.ColourSchemeI; import jalview.schemes.PIDColourScheme; import jalview.schemes.ResidueProperties; @@ -49,6 +51,7 @@ import jalview.structure.CommandListener; import jalview.structure.StructureSelectionManager; import jalview.structure.VamsasSource; import jalview.util.Comparison; +import jalview.util.MapList; import jalview.util.MappingUtils; import jalview.viewmodel.styles.ViewStyle; import jalview.workers.AlignCalcManager; @@ -56,7 +59,6 @@ import jalview.workers.ComplementConsensusThread; import jalview.workers.ConsensusThread; import jalview.workers.StrucConsensusThread; -import java.awt.Color; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.BitSet; @@ -65,7 +67,6 @@ import java.util.HashMap; import java.util.Hashtable; import java.util.List; import java.util.Map; -import java.util.Set; /** * base class holding visualization and analysis attributes and common logic for @@ -837,15 +838,36 @@ public abstract class AlignmentViewport implements AlignViewportI, /* * A separate thread to compute cDNA consensus for a protein alignment + * which has mapping to cDNA */ final AlignmentI al = this.getAlignment(); if (!al.isNucleotide() && al.getCodonFrames() != null && !al.getCodonFrames().isEmpty()) { - if (calculator - .getRegisteredWorkersOfClass(ComplementConsensusThread.class) == null) + /* + * fudge - check first for protein-to-nucleotide mappings + * (we don't want to do this for protein-to-protein) + */ + 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) { - calculator.registerWorker(new ComplementConsensusThread(this, ap)); + if (calculator + .getRegisteredWorkersOfClass(ComplementConsensusThread.class) == null) + { + calculator + .registerWorker(new ComplementConsensusThread(this, ap)); + } } } } @@ -1065,6 +1087,7 @@ public abstract class AlignmentViewport implements AlignViewportI, { updateHiddenColumns(); } + isColSelChanged(true); } /** @@ -1085,6 +1108,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(); @@ -1193,8 +1223,7 @@ public abstract class AlignmentViewport implements AlignViewportI, */ public boolean isColSelChanged(boolean b) { - int hc = (colSel == null || colSel.isEmpty()) ? -1 : colSel - .hashCode(); + int hc = (colSel == null || colSel.isEmpty()) ? -1 : colSel.hashCode(); if (hc != -1 && hc != colselhash) { if (b) @@ -1224,7 +1253,7 @@ public abstract class AlignmentViewport implements AlignViewportI, protected boolean showConsensus = true; - private Map sequenceColours = new HashMap(); + private Map sequenceColours = new HashMap(); protected SequenceAnnotationOrder sortAnnotationsBy = null; @@ -1295,7 +1324,7 @@ public abstract class AlignmentViewport implements AlignViewportI, colSel.hideSelectedColumns(); setSelectionGroup(null); - + isColSelChanged(true); } public void hideColumns(int start, int end) @@ -1308,17 +1337,19 @@ public abstract class AlignmentViewport implements AlignViewportI, { colSel.hideColumns(start, end); } + isColSelChanged(true); } public void showColumn(int col) { colSel.revealHiddenColumns(col); - + isColSelChanged(true); } public void showAllHiddenColumns() { colSel.revealAllHiddenColumns(); + isColSelChanged(true); } // common hide/show seq stuff @@ -1398,6 +1429,39 @@ public abstract class AlignmentViewport implements AlignViewportI, } /** + * Hides the specified sequence, or the sequences it represents + * + * @param sequence + * the sequence to hide, or keep as representative + * @param representGroup + * if true, hide the current selection group except for the + * representative sequence + */ + public void hideSequences(SequenceI sequence, boolean representGroup) + { + if (selectionGroup == null || selectionGroup.getSize() < 1) + { + hideSequence(new SequenceI[] { sequence }); + return; + } + + if (representGroup) + { + hideRepSequences(sequence, selectionGroup); + setSelectionGroup(null); + return; + } + + int gsize = selectionGroup.getSize(); + SequenceI[] hseqs = selectionGroup.getSequences().toArray( + new SequenceI[gsize]); + + hideSequence(hseqs); + setSelectionGroup(null); + sendSelection(); + } + + /** * Set visibility for any annotations for the given sequence. * * @param sequenceI @@ -1405,11 +1469,15 @@ public abstract class AlignmentViewport implements AlignViewportI, protected void setSequenceAnnotationsVisible(SequenceI sequenceI, boolean visible) { - for (AlignmentAnnotation ann : alignment.getAlignmentAnnotation()) + AlignmentAnnotation[] anns = alignment.getAlignmentAnnotation(); + if (anns != null) { - if (ann.sequenceRef == sequenceI) + for (AlignmentAnnotation ann : anns) { - ann.visible = visible; + if (ann.sequenceRef == sequenceI) + { + ann.visible = visible; + } } } } @@ -1424,7 +1492,7 @@ public abstract class AlignmentViewport implements AlignViewportI, if (hiddenRepSequences == null) { - hiddenRepSequences = new Hashtable(); + hiddenRepSequences = new Hashtable(); } hiddenRepSequences.put(repSequence, sg); @@ -1450,13 +1518,42 @@ public abstract class AlignmentViewport implements AlignViewportI, } + /** + * + * @return null or the current reference sequence + */ + public SequenceI getReferenceSeq() + { + return alignment.getSeqrep(); + } + + /** + * @param seq + * @return true iff seq is the reference for the alignment + */ + public boolean isReferenceSeq(SequenceI seq) + { + return alignment.getSeqrep() == seq; + } + + /** + * + * @param seq + * @return true if there are sequences represented by this sequence that are + * currently hidden + */ public boolean isHiddenRepSequence(SequenceI seq) { - return alignment.getSeqrep() == seq - || (hiddenRepSequences != null && hiddenRepSequences + return (hiddenRepSequences != null && hiddenRepSequences .containsKey(seq)); } + /** + * + * @param seq + * @return null or a sequence group containing the sequences that seq + * represents + */ public SequenceGroup getRepresentedSequences(SequenceI seq) { return (SequenceGroup) (hiddenRepSequences == null ? null @@ -1544,6 +1641,13 @@ public abstract class AlignmentViewport implements AlignViewportI, @Override public String[] getViewAsString(boolean selectedRegionOnly) { + return getViewAsString(selectedRegionOnly, true); + } + + @Override + public String[] getViewAsString(boolean selectedRegionOnly, + boolean exportHiddenSeqs) + { String[] selection = null; SequenceI[] seqs = null; int i, iSize; @@ -1557,13 +1661,13 @@ public abstract class AlignmentViewport implements AlignViewportI, } else { - if (alignment.getHiddenSequences() != null) + if (hasHiddenRows() && exportHiddenSeqs) { - iSize = alignment.getHiddenSequences().getFullAlignment() - .getHeight(); - seqs = alignment.getHiddenSequences().getFullAlignment() - .getSequencesArray(); - end = alignment.getHiddenSequences().getFullAlignment().getWidth(); + AlignmentI fullAlignment = alignment.getHiddenSequences() + .getFullAlignment(); + iSize = fullAlignment.getHeight(); + seqs = fullAlignment.getSequencesArray(); + end = fullAlignment.getWidth(); } else { @@ -1780,14 +1884,30 @@ public abstract class AlignmentViewport implements AlignViewportI, { if (!alignment.isNucleotide()) { - final Set codonMappings = alignment + final List codonMappings = alignment .getCodonFrames(); if (codonMappings != null && !codonMappings.isEmpty()) { - complementConsensus = new AlignmentAnnotation("cDNA Consensus", - "PID for cDNA", new Annotation[1], 0f, 100f, - AlignmentAnnotation.BAR_GRAPH); - initConsensus(complementConsensus); + 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, + AlignmentAnnotation.BAR_GRAPH); + initConsensus(complementConsensus); + } } } } @@ -2009,14 +2129,14 @@ public abstract class AlignmentViewport implements AlignViewportI, } @Override - public Color getSequenceColour(SequenceI seq) + public ColorI getSequenceColour(SequenceI seq) { - Color sqc = sequenceColours.get(seq); - return (sqc == null ? Color.white : sqc); + ColorI sqc = sequenceColours.get(seq); + return (sqc == null ? Colour.white : sqc); } @Override - public void setSequenceColour(SequenceI seq, Color col) + public void setSequenceColour(SequenceI seq, ColorI col) { if (col == null) { @@ -2099,7 +2219,7 @@ public abstract class AlignmentViewport implements AlignViewportI, public boolean areFeaturesDisplayed() { return featuresDisplayed != null - && featuresDisplayed.getRegisterdFeaturesCount() > 0; + && featuresDisplayed.getRegisteredFeaturesCount() > 0; } /** @@ -2173,7 +2293,7 @@ public abstract class AlignmentViewport implements AlignViewportI, * @see jalview.api.ViewStyleI#getTextColour() */ @Override - public Color getTextColour() + public ColorI getTextColour() { return viewStyle.getTextColour(); } @@ -2183,7 +2303,7 @@ public abstract class AlignmentViewport implements AlignViewportI, * @see jalview.api.ViewStyleI#getTextColour2() */ @Override - public Color getTextColour2() + public ColorI getTextColour2() { return viewStyle.getTextColour2(); } @@ -2254,7 +2374,7 @@ public abstract class AlignmentViewport implements AlignViewportI, * @see jalview.api.ViewStyleI#setTextColour(java.awt.Color) */ @Override - public void setTextColour(Color textColour) + public void setTextColour(ColorI textColour) { viewStyle.setTextColour(textColour); } @@ -2274,7 +2394,7 @@ public abstract class AlignmentViewport implements AlignViewportI, * @see jalview.api.ViewStyleI#setTextColour2(java.awt.Color) */ @Override - public void setTextColour2(Color textColour2) + public void setTextColour2(ColorI textColour2) { viewStyle.setTextColour2(textColour2); } @@ -2580,7 +2700,7 @@ public abstract class AlignmentViewport implements AlignViewportI, { return 0; } - final Set mappings = proteinAlignment + final List mappings = proteinAlignment .getCodonFrames(); /* @@ -2604,6 +2724,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); @@ -2615,15 +2736,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 @@ -2631,7 +2753,68 @@ public abstract class AlignmentViewport implements AlignViewportI, return 0; } MappingUtils.addSearchResults(sr, sequence, - sequence.findPosition(middleColumn), mappings); + sequence.findPosition(middleColumn), seqMappings); return seqOffset; } + + /** + * synthesize a column selection if none exists so it covers the given + * selection group. if wholewidth is false, no column selection is made if the + * selection group covers the whole alignment width. + * + * @param sg + * @param wholewidth + */ + public void expandColSelection(SequenceGroup sg, boolean wholewidth) + { + int sgs, sge; + if (sg != null + && (sgs = sg.getStartRes()) >= 0 + && sg.getStartRes() <= (sge = sg.getEndRes()) + && !this.hasSelectedColumns()) + { + if (!wholewidth && alignment.getWidth() == (1 + sge - sgs)) + { + // do nothing + return; + } + if (colSel == null) + { + colSel = new ColumnSelection(); + } + for (int cspos = sg.getStartRes(); cspos <= sg.getEndRes(); cspos++) + { + colSel.addElement(cspos); + } + } + } + + /** + * 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; + } }