X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fviewmodel%2FAlignmentViewport.java;h=2cfc1e6d3893a5a1c53b846610cda83b322f08ef;hb=1ae9824ef37ce4ed36d1da986003474b47d1ab11;hp=e8f13037d2c7d41dad873bbbda8f31bed43b4605;hpb=c96778d1064ff5cecdbbbe4a02891010b868532a;p=jalview.git diff --git a/src/jalview/viewmodel/AlignmentViewport.java b/src/jalview/viewmodel/AlignmentViewport.java index e8f1303..2cfc1e6 100644 --- a/src/jalview/viewmodel/AlignmentViewport.java +++ b/src/jalview/viewmodel/AlignmentViewport.java @@ -1,6 +1,6 @@ /* - * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2) - * 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. * @@ -26,10 +26,13 @@ import jalview.api.AlignViewportI; import jalview.api.AlignmentViewPanel; import jalview.api.FeaturesDisplayedI; import jalview.api.ViewStyleI; +import jalview.commands.CommandI; +import jalview.datamodel.AlignedCodonFrame; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; import jalview.datamodel.AlignmentView; import jalview.datamodel.Annotation; +import jalview.datamodel.CigarArray; import jalview.datamodel.ColumnSelection; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceCollectionI; @@ -39,18 +42,25 @@ import jalview.schemes.Blosum62ColourScheme; import jalview.schemes.ColourSchemeI; import jalview.schemes.PIDColourScheme; import jalview.schemes.ResidueProperties; +import jalview.structure.CommandListener; +import jalview.structure.StructureSelectionManager; +import jalview.structure.VamsasSource; 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.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 java.util.Vector; +import java.util.Set; /** * base class holding visualization and analysis attributes and common logic for @@ -60,10 +70,76 @@ import java.util.Vector; * */ public abstract class AlignmentViewport implements AlignViewportI, - ViewStyleI + ViewStyleI, CommandListener, VamsasSource { protected ViewStyleI viewStyle = new ViewStyle(); - + + /** + * A viewport that hosts the cDna view of this (protein), or vice versa (if + * set). + */ + AlignViewportI codingComplement = null; + + FeaturesDisplayedI featuresDisplayed = null; + + protected Deque historyList = new ArrayDeque(); + + protected Deque redoList = new ArrayDeque(); + + /** + * @param name + * @see jalview.api.ViewStyleI#setFontName(java.lang.String) + */ + public void setFontName(String name) + { + viewStyle.setFontName(name); + } + + /** + * @param style + * @see jalview.api.ViewStyleI#setFontStyle(int) + */ + public void setFontStyle(int style) + { + viewStyle.setFontStyle(style); + } + + /** + * @param size + * @see jalview.api.ViewStyleI#setFontSize(int) + */ + public void setFontSize(int size) + { + viewStyle.setFontSize(size); + } + + /** + * @return + * @see jalview.api.ViewStyleI#getFontStyle() + */ + public int getFontStyle() + { + return viewStyle.getFontStyle(); + } + + /** + * @return + * @see jalview.api.ViewStyleI#getFontName() + */ + public String getFontName() + { + return viewStyle.getFontName(); + } + + /** + * @return + * @see jalview.api.ViewStyleI#getFontSize() + */ + public int getFontSize() + { + return viewStyle.getFontSize(); + } + /** * @param upperCasebold * @see jalview.api.ViewStyleI#setUpperCasebold(boolean) @@ -530,12 +606,12 @@ public abstract class AlignmentViewport implements AlignViewportI, || cs instanceof Blosum62ColourScheme) { sg.cs.setThreshold(viewStyle.getThreshold(), - getIgnoreGapsConsensus()); + isIgnoreGapsConsensus()); recalc = true; } else { - sg.cs.setThreshold(0, getIgnoreGapsConsensus()); + sg.cs.setThreshold(0, isIgnoreGapsConsensus()); } if (getConservationSelected()) @@ -569,6 +645,8 @@ public abstract class AlignmentViewport implements AlignViewportI, protected AlignmentAnnotation consensus; + protected AlignmentAnnotation complementConsensus; + protected AlignmentAnnotation strucConsensus; protected AlignmentAnnotation conservation; @@ -585,6 +663,11 @@ public abstract class AlignmentViewport implements AlignViewportI, protected Hashtable[] hconsensus = null; /** + * results of cDNA complement consensus visible portion of view + */ + protected Hashtable[] hcomplementConsensus = null; + + /** * results of secondary structure base pair consensus for visible portion of * view */ @@ -614,7 +697,12 @@ public abstract class AlignmentViewport implements AlignViewportI, public void setSequenceConsensusHash(Hashtable[] hconsensus) { this.hconsensus = hconsensus; + } + @Override + public void setComplementConsensusHash(Hashtable[] hconsensus) + { + this.hcomplementConsensus = hconsensus; } @Override @@ -624,6 +712,12 @@ public abstract class AlignmentViewport implements AlignViewportI, } @Override + public Hashtable[] getComplementConsensusHash() + { + return hcomplementConsensus; + } + + @Override public Hashtable[] getRnaStructureConsensusHash() { return hStrucConsensus; @@ -655,6 +749,12 @@ public abstract class AlignmentViewport implements AlignViewportI, } @Override + public AlignmentAnnotation getComplementConsensusAnnotation() + { + return complementConsensus; + } + + @Override public AlignmentAnnotation getAlignmentStrucConsensusAnnotation() { return strucConsensus; @@ -695,6 +795,20 @@ public abstract class AlignmentViewport implements AlignViewportI, { calculator.registerWorker(new ConsensusThread(this, ap)); } + + /* + * A separate thread to compute cDNA consensus for a protein alignment + */ + final AlignmentI al = this.getAlignment(); + if (!al.isNucleotide() && al.getCodonFrames() != null + && !al.getCodonFrames().isEmpty()) + { + if (calculator + .getRegisteredWorkersOfClass(ComplementConsensusThread.class) == null) + { + calculator.registerWorker(new ComplementConsensusThread(this, ap)); + } + } } // --------START Structure Conservation @@ -799,6 +913,7 @@ public abstract class AlignmentViewport implements AlignViewportI, // annotation update method from alignframe to viewport this.showSequenceLogo = showSequenceLogo; calculator.updateAnnotationFor(ConsensusThread.class); + calculator.updateAnnotationFor(ComplementConsensusThread.class); calculator.updateAnnotationFor(StrucConsensusThread.class); } this.showSequenceLogo = showSequenceLogo; @@ -981,6 +1096,7 @@ public abstract class AlignmentViewport implements AlignViewportI, */ protected String viewId = null; + @Override public String getViewId() { if (viewId == null) @@ -1055,7 +1171,7 @@ public abstract class AlignmentViewport implements AlignViewportI, } @Override - public boolean getIgnoreGapsConsensus() + public boolean isIgnoreGapsConsensus() { return ignoreGapsInConsensusCalculation; } @@ -1072,7 +1188,7 @@ public abstract class AlignmentViewport implements AlignViewportI, protected boolean showConsensus = true; - Hashtable sequenceColours; + private Map sequenceColours = new HashMap(); /** * Property change listener for changes in alignment @@ -1309,9 +1425,6 @@ public abstract class AlignmentViewport implements AlignViewportI, } @Override - public abstract void sendSelection(); - - @Override public void invertColumnSelection() { colSel.invertColumnSelection(0, alignment.getWidth()); @@ -1333,10 +1446,8 @@ public abstract class AlignmentViewport implements AlignViewportI, AlignmentAnnotation[] annots = alignment.getAlignmentAnnotation(); for (int i = 0; i < sequences.length; i++) { - sequences[i] = new Sequence(sequences[i], annots); // construct new - // sequence with - // subset of visible - // annotation + // construct new sequence with subset of visible annotation + sequences[i] = new Sequence(sequences[i], annots); } } else @@ -1365,10 +1476,10 @@ public abstract class AlignmentViewport implements AlignViewportI, @Override - public jalview.datamodel.CigarArray getViewAsCigars( + public CigarArray getViewAsCigars( boolean selectedRegionOnly) { - return new jalview.datamodel.CigarArray(alignment, colSel, + return new CigarArray(alignment, colSel, (selectedRegionOnly ? selectionGroup : null)); } @@ -1430,9 +1541,9 @@ public abstract class AlignmentViewport implements AlignViewportI, @Override - public int[][] getVisibleRegionBoundaries(int min, int max) + public List getVisibleRegionBoundaries(int min, int max) { - Vector regions = new Vector(); + ArrayList regions = new ArrayList(); int start = min; int end = max; @@ -1456,7 +1567,7 @@ public abstract class AlignmentViewport implements AlignViewportI, } } - regions.addElement(new int[] + regions.add(new int[] { start, end }); if (colSel != null && colSel.hasHiddenColumns()) @@ -1468,10 +1579,7 @@ public abstract class AlignmentViewport implements AlignViewportI, int[][] startEnd = new int[regions.size()][2]; - regions.copyInto(startEnd); - - return startEnd; - + return regions; } @Override @@ -1606,21 +1714,42 @@ public abstract class AlignmentViewport implements AlignViewportI, { initRNAStructure(); } - initConsensus(); + consensus = new AlignmentAnnotation("Consensus", "PID", + new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH); + initConsensus(consensus); + + initComplementConsensus(); } } - private void initConsensus() + /** + * If this is a protein alignment and there are mappings to cDNA, add the cDNA + * consensus annotation. + */ + protected void initComplementConsensus() { + if (!alignment.isNucleotide()) + { + final Set 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); + } + } + } - consensus = new AlignmentAnnotation("Consensus", "PID", - new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH); - consensus.hasText = true; - consensus.autoCalculated = true; + private void initConsensus(AlignmentAnnotation aa) + { + aa.hasText = true; + aa.autoCalculated = true; if (showConsensus) { - alignment.addAnnotation(consensus); + alignment.addAnnotation(aa); } } @@ -1682,57 +1811,57 @@ public abstract class AlignmentViewport implements AlignViewportI, public int calcPanelHeight() { // setHeight of panels - AlignmentAnnotation[] aa = getAlignment().getAlignmentAnnotation(); + AlignmentAnnotation[] anns = getAlignment().getAlignmentAnnotation(); int height = 0; int charHeight = getCharHeight(); - if (aa != null) + if (anns != null) { BitSet graphgrp = new BitSet(); - for (int i = 0; i < aa.length; i++) + for (AlignmentAnnotation aa : anns) { - if (aa[i] == null) + if (aa == null) { System.err.println("Null annotation row: ignoring."); continue; } - if (!aa[i].visible) + if (!aa.visible) { continue; } - if (aa[i].graphGroup > -1) + if (aa.graphGroup > -1) { - if (graphgrp.get(aa[i].graphGroup)) + if (graphgrp.get(aa.graphGroup)) { continue; } else { - graphgrp.set(aa[i].graphGroup); + graphgrp.set(aa.graphGroup); } } - aa[i].height = 0; + aa.height = 0; - if (aa[i].hasText) + if (aa.hasText) { - aa[i].height += charHeight; + aa.height += charHeight; } - if (aa[i].hasIcons) + if (aa.hasIcons) { - aa[i].height += 16; + aa.height += 16; } - if (aa[i].graph > 0) + if (aa.graph > 0) { - aa[i].height += aa[i].graphHeight; + aa.height += aa.graphHeight; } - if (aa[i].height == 0) + if (aa.height == 0) { - aa[i].height = 20; + aa.height = 20; } - height += aa[i].height; + height += aa.height; } } if (height == 0) @@ -1822,35 +1951,22 @@ public abstract class AlignmentViewport implements AlignViewportI, viewStyle.setDisplayReferenceSeq(displayReferenceSeq); } + @Override public boolean isColourByReferenceSeq() { return alignment.hasSeqrep() && viewStyle.isColourByReferenceSeq(); } - @Override public Color getSequenceColour(SequenceI seq) { - Color sqc = Color.white; - if (sequenceColours != null) - { - sqc = (Color) sequenceColours.get(seq); - if (sqc == null) - { - sqc = Color.white; - } - } - return sqc; + Color sqc = sequenceColours.get(seq); + return (sqc == null ? Color.white : sqc); } @Override public void setSequenceColour(SequenceI seq, Color col) { - if (sequenceColours == null) - { - sequenceColours = new Hashtable(); - } - if (col == null) { sequenceColours.remove(seq); @@ -1864,10 +1980,6 @@ public abstract class AlignmentViewport implements AlignViewportI, @Override public void updateSequenceIdColours() { - if (sequenceColours == null) - { - sequenceColours = new Hashtable(); - } for (SequenceGroup sg : alignment.getGroups()) { if (sg.idColour != null) @@ -1883,10 +1995,42 @@ public abstract class AlignmentViewport implements AlignViewportI, @Override public void clearSequenceColours() { - sequenceColours = null; + sequenceColours.clear(); }; - FeaturesDisplayedI featuresDisplayed = null; + @Override + public AlignViewportI getCodingComplement() + { + 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 setCodingComplement(AlignViewportI av) + { + if (this == av) + { + System.err.println("Ignoring recursive setCodingComplement request"); + } + else + { + this.codingComplement = av; + // avoid infinite recursion! + if (av.getCodingComplement() != this) + { + av.setCodingComplement(this); + } + } + } + + @Override + public boolean isNucleotide() + { + return getAlignment() == null ? false : getAlignment().isNucleotide(); + } @Override public FeaturesDisplayedI getFeaturesDisplayed() @@ -2026,7 +2170,6 @@ public abstract class AlignmentViewport implements AlignViewportI, { return viewStyle.isShowColourText(); } - /** * @return * @see jalview.api.ViewStyleI#isShowSeqFeaturesHeight() @@ -2082,4 +2225,165 @@ public abstract class AlignmentViewport implements AlignViewportI, viewStyle.setTextColour2(textColour2); } + @Override + public ViewStyleI getViewStyle() + { + return new ViewStyle(viewStyle); + } + + @Override + public void setViewStyle(ViewStyleI settingsForView) + { + viewStyle = new ViewStyle(settingsForView); + } + + @Override + public boolean sameStyle(ViewStyleI them) + { + return viewStyle.sameStyle(them); + } + + /** + * @return + * @see jalview.api.ViewStyleI#getIdWidth() + */ + public int getIdWidth() + { + return viewStyle.getIdWidth(); + } + + /** + * @param i + * @see jalview.api.ViewStyleI#setIdWidth(int) + */ + public void setIdWidth(int i) + { + viewStyle.setIdWidth(i); + } + + /** + * @return + * @see jalview.api.ViewStyleI#isCentreColumnLabels() + */ + public boolean isCentreColumnLabels() + { + return viewStyle.isCentreColumnLabels(); + } + + /** + * @param centreColumnLabels + * @see jalview.api.ViewStyleI#setCentreColumnLabels(boolean) + */ + public void setCentreColumnLabels(boolean centreColumnLabels) + { + viewStyle.setCentreColumnLabels(centreColumnLabels); + } + + /** + * @param showdbrefs + * @see jalview.api.ViewStyleI#setShowDBRefs(boolean) + */ + public void setShowDBRefs(boolean showdbrefs) + { + viewStyle.setShowDBRefs(showdbrefs); + } + + /** + * @return + * @see jalview.api.ViewStyleI#isShowDBRefs() + */ + public boolean isShowDBRefs() + { + return viewStyle.isShowDBRefs(); + } + + /** + * @return + * @see jalview.api.ViewStyleI#isShowNPFeats() + */ + public boolean isShowNPFeats() + { + return viewStyle.isShowNPFeats(); + } + + /** + * @param shownpfeats + * @see jalview.api.ViewStyleI#setShowNPFeats(boolean) + */ + public void setShowNPFeats(boolean shownpfeats) + { + viewStyle.setShowNPFeats(shownpfeats); + } + + public abstract StructureSelectionManager getStructureSelectionManager(); + + /** + * Add one command to the command history list. + * + * @param command + */ + public void addToHistoryList(CommandI command) + { + if (this.historyList != null) + { + this.historyList.push(command); + broadcastCommand(command, false); + } + } + + protected void broadcastCommand(CommandI command, boolean undo) + { + getStructureSelectionManager().commandPerformed(command, undo, getVamsasSource()); + } + + /** + * Add one command to the command redo list. + * + * @param command + */ + public void addToRedoList(CommandI command) + { + if (this.redoList != null) + { + this.redoList.push(command); + } + broadcastCommand(command, true); + } + + /** + * Clear the command redo list. + */ + public void clearRedoList() + { + if (this.redoList != null) + { + this.redoList.clear(); + } + } + + public void setHistoryList(Deque list) + { + this.historyList = list; + } + + public Deque getHistoryList() + { + return this.historyList; + } + + public void setRedoList(Deque list) + { + this.redoList = list; + } + + public Deque getRedoList() + { + return this.redoList; + } + + @Override + public VamsasSource getVamsasSource() + { + return this; + } }