/* * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7) * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle * * 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. * * 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 . */ /* * Jalview - A Sequence Alignment Editor and Viewer * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle * * This program 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 2 * of the License, or (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ package jalview.gui; import java.util.*; import java.awt.*; import jalview.analysis.*; import jalview.api.StructureSelectionManagerProvider; import jalview.bin.*; import jalview.datamodel.*; import jalview.schemes.*; import jalview.structure.SelectionSource; import jalview.structure.StructureSelectionManager; import jalview.structure.VamsasSource; /** * DOCUMENT ME! * * @author $author$ * @version $Revision: 1.141 $ */ public class AlignViewport implements SelectionSource, VamsasSource { private static final int RIGHT_JUSTIFY = 1; int startRes; int endRes; int startSeq; int endSeq; boolean showJVSuffix = true; boolean showText = true; boolean showColourText = false; boolean showBoxes = true; boolean wrapAlignment = false; boolean renderGaps = true; boolean showSequenceFeatures = false; boolean showAnnotation = true; boolean colourAppliesToAllGroups = true; ColourSchemeI globalColourScheme = null; boolean conservationColourSelected = false; boolean abovePIDThreshold = false; SequenceGroup selectionGroup; int charHeight; int charWidth; boolean validCharWidth; int wrappedWidth; Font font; boolean seqNameItalics; AlignmentI alignment; ColumnSelection colSel = new ColumnSelection(); int threshold; int increment; NJTree currentTree = null; boolean scaleAboveWrapped = false; boolean scaleLeftWrapped = true; boolean scaleRightWrapped = true; boolean hasHiddenColumns = false; boolean hasHiddenRows = false; boolean showHiddenMarkers = true; boolean cursorMode = false; /** * Keys are the feature types which are currently visible. Note: Values are * not used! */ Hashtable featuresDisplayed = null; /** DOCUMENT ME!! */ public Hashtable[] hconsensus; public Hashtable[] hStrucConsensus; AlignmentAnnotation consensus; AlignmentAnnotation strucConsensus; AlignmentAnnotation conservation; AlignmentAnnotation quality; AlignmentAnnotation[] groupConsensus; AlignmentAnnotation[] groupConservation; boolean autoCalculateConsensus = true; boolean autoCalculateStrucConsensus = true; /** DOCUMENT ME!! */ public int ConsPercGaps = 25; // JBPNote : This should be a scalable property! // JBPNote Prolly only need this in the applet version. private java.beans.PropertyChangeSupport changeSupport = new java.beans.PropertyChangeSupport( this); boolean ignoreGapsInConsensusCalculation = false; boolean isDataset = false; boolean antiAlias = false; boolean padGaps = false; Rectangle explodedPosition; String viewName; String sequenceSetID; boolean gatherViewsHere = false; Stack historyList = new Stack(); Stack redoList = new Stack(); Hashtable sequenceColours; int thresholdTextColour = 0; Color textColour = Color.black; Color textColour2 = Color.white; boolean rightAlignIds = false; Hashtable hiddenRepSequences; boolean sortByTree; /** * Creates a new AlignViewport object. * * @param al * alignment to view */ public AlignViewport(AlignmentI al) { setAlignment(al); init(); } /** * Create a new AlignViewport object with a specific sequence set ID * * @param al * @param seqsetid * (may be null - but potential for ambiguous constructor exception) */ public AlignViewport(AlignmentI al, String seqsetid) { this(al, seqsetid, null); } public AlignViewport(AlignmentI al, String seqsetid, String viewid) { sequenceSetID = seqsetid; viewId = viewid; // TODO remove these once 2.4.VAMSAS release finished if (Cache.log != null && Cache.log.isDebugEnabled() && seqsetid != null) { Cache.log.debug("Setting viewport's sequence set id : " + sequenceSetID); } if (Cache.log != null && Cache.log.isDebugEnabled() && viewId != null) { Cache.log.debug("Setting viewport's view id : " + viewId); } setAlignment(al); init(); } /** * Create a new AlignViewport with hidden regions * * @param al * AlignmentI * @param hiddenColumns * ColumnSelection */ public AlignViewport(AlignmentI al, ColumnSelection hiddenColumns) { setAlignment(al); if (hiddenColumns != null) { this.colSel = hiddenColumns; if (hiddenColumns.getHiddenColumns() != null && hiddenColumns.getHiddenColumns().size() > 0) { hasHiddenColumns = true; } else { hasHiddenColumns = false; } } init(); } /** * New viewport with hidden columns and an existing sequence set id * * @param al * @param hiddenColumns * @param seqsetid * (may be null) */ public AlignViewport(AlignmentI al, ColumnSelection hiddenColumns, String seqsetid) { this(al, hiddenColumns, seqsetid, null); } /** * New viewport with hidden columns and an existing sequence set id and viewid * * @param al * @param hiddenColumns * @param seqsetid * (may be null) * @param viewid * (may be null) */ public AlignViewport(AlignmentI al, ColumnSelection hiddenColumns, String seqsetid, String viewid) { sequenceSetID = seqsetid; viewId = viewid; // TODO remove these once 2.4.VAMSAS release finished if (Cache.log != null && Cache.log.isDebugEnabled() && seqsetid != null) { Cache.log.debug("Setting viewport's sequence set id : " + sequenceSetID); } if (Cache.log != null && Cache.log.isDebugEnabled() && viewId != null) { Cache.log.debug("Setting viewport's view id : " + viewId); } setAlignment(al); if (hiddenColumns != null) { this.colSel = hiddenColumns; if (hiddenColumns.getHiddenColumns() != null && hiddenColumns.getHiddenColumns().size() > 0) { hasHiddenColumns = true; } else { hasHiddenColumns = false; } } init(); } void init() { this.startRes = 0; this.endRes = alignment.getWidth() - 1; this.startSeq = 0; this.endSeq = alignment.getHeight() - 1; antiAlias = Cache.getDefault("ANTI_ALIAS", false); showJVSuffix = Cache.getDefault("SHOW_JVSUFFIX", true); showAnnotation = Cache.getDefault("SHOW_ANNOTATIONS", true); rightAlignIds = Cache.getDefault("RIGHT_ALIGN_IDS", false); centreColumnLabels = Cache.getDefault("CENTRE_COLUMN_LABELS", false); autoCalculateConsensus = Cache.getDefault("AUTO_CALC_CONSENSUS", true); padGaps = Cache.getDefault("PAD_GAPS", true); shownpfeats = Cache.getDefault("SHOW_NPFEATS_TOOLTIP", true); showdbrefs = Cache.getDefault("SHOW_DBREFS_TOOLTIP", true); String fontName = Cache.getDefault("FONT_NAME", "SansSerif"); String fontStyle = Cache.getDefault("FONT_STYLE", Font.PLAIN + ""); String fontSize = Cache.getDefault("FONT_SIZE", "10"); seqNameItalics = Cache.getDefault("ID_ITALICS", true); int style = 0; if (fontStyle.equals("bold")) { style = 1; } else if (fontStyle.equals("italic")) { style = 2; } setFont(new Font(fontName, style, Integer.parseInt(fontSize))); alignment .setGapCharacter(Cache.getDefault("GAP_SYMBOL", "-").charAt(0)); // We must set conservation and consensus before setting colour, // as Blosum and Clustal require this to be done if (hconsensus == null && !isDataset) { if (!alignment.isNucleotide()) { conservation = new AlignmentAnnotation("Conservation", "Conservation of total alignment less than " + ConsPercGaps + "% gaps", new Annotation[1], 0f, 11f, AlignmentAnnotation.BAR_GRAPH); conservation.hasText = true; conservation.autoCalculated = true; if (Cache.getDefault("SHOW_CONSERVATION", true)) { alignment.addAnnotation(conservation); } if (Cache.getDefault("SHOW_QUALITY", true)) { quality = new AlignmentAnnotation("Quality", "Alignment Quality based on Blosum62 scores", new Annotation[1], 0f, 11f, AlignmentAnnotation.BAR_GRAPH); quality.hasText = true; quality.autoCalculated = true; alignment.addAnnotation(quality); } showGroupConservation = Cache.getDefault("SHOW_GROUP_CONSERVATION", false); { } } showConsensusHistogram = Cache.getDefault("SHOW_CONSENSUS_HISTOGRAM", true); showSequenceLogo = Cache.getDefault("SHOW_CONSENSUS_LOGO", false); showGroupConsensus = Cache.getDefault("SHOW_GROUP_CONSENSUS", false); // TODO: add menu option action that nulls or creates consensus object // depending on if the user wants to see the annotation or not in a // specific alignment consensus = new AlignmentAnnotation("Consensus", "PID", new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH); consensus.hasText = true; consensus.autoCalculated = true; if (alignment.isNucleotide() && alignment.hasRNAStructure()) { strucConsensus = new AlignmentAnnotation("StrucConsensus", "PID", new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH); strucConsensus.hasText = true; strucConsensus.autoCalculated = true; } if (Cache.getDefault("SHOW_IDENTITY", true)) { alignment.addAnnotation(consensus); // TODO: Make own if for structure if (alignment.isNucleotide() && alignment.hasRNAStructure()) { alignment.addAnnotation(strucConsensus); } } } if (jalview.bin.Cache.getProperty("DEFAULT_COLOUR") != null) { globalColourScheme = ColourSchemeProperty.getColour(alignment, jalview.bin.Cache.getProperty("DEFAULT_COLOUR")); if (globalColourScheme instanceof UserColourScheme) { globalColourScheme = UserDefinedColours.loadDefaultColours(); ((UserColourScheme) globalColourScheme).setThreshold(0, getIgnoreGapsConsensus()); } if (globalColourScheme != null) { globalColourScheme.setConsensus(hconsensus); } } wrapAlignment = jalview.bin.Cache.getDefault("WRAP_ALIGNMENT", false); showUnconserved = jalview.bin.Cache.getDefault("SHOW_UNCONSERVED", false); sortByTree = jalview.bin.Cache.getDefault("SORT_BY_TREE", false); followSelection = jalview.bin.Cache.getDefault("FOLLOW_SELECTIONS", true); } /** * set the flag * * @param b * features are displayed if true */ public void setShowSequenceFeatures(boolean b) { showSequenceFeatures = b; } public boolean getShowSequenceFeatures() { return showSequenceFeatures; } ConservationThread conservationThread; ConsensusThread consensusThread; StrucConsensusThread strucConsensusThread; boolean consUpdateNeeded = false; static boolean UPDATING_CONSENSUS = false; static boolean UPDATING_STRUC_CONSENSUS = false; static boolean UPDATING_CONSERVATION = false; boolean updatingConsensus = false; boolean updatingStrucConsensus = false; boolean updatingConservation = false; /** * centre columnar annotation labels in displayed alignment annotation TODO: * add to jalviewXML and annotation display settings */ boolean centreColumnLabels = false; private boolean showdbrefs; private boolean shownpfeats; /** * trigger update of conservation annotation */ public void updateConservation(final AlignmentPanel ap) { // see note in mantis : issue number 8585 if (alignment.isNucleotide() || conservation == null || !autoCalculateConsensus) { return; } conservationThread = new ConservationThread(this, ap); conservationThread.start(); } /** * trigger update of consensus annotation */ public void updateConsensus(final AlignmentPanel ap) { // see note in mantis : issue number 8585 if (consensus == null || !autoCalculateConsensus) { return; } consensusThread = new ConsensusThread(ap); consensusThread.start(); } class ConsensusThread extends Thread { AlignmentPanel ap; public ConsensusThread(AlignmentPanel ap) { this.ap = ap; } public void run() { updatingConsensus = true; while (UPDATING_CONSENSUS) { try { if (ap != null) { ap.paintAlignment(false); } Thread.sleep(200); } catch (Exception ex) { ex.printStackTrace(); } } UPDATING_CONSENSUS = true; try { int aWidth = (alignment != null) ? alignment.getWidth() : -1; // null // pointer // possibility // here. if (aWidth <= 0) { updatingConsensus = false; UPDATING_CONSENSUS = false; return; } consensus.annotations = null; consensus.annotations = new Annotation[aWidth]; hconsensus = new Hashtable[aWidth]; AAFrequency.calculate(alignment.getSequencesArray(), 0, alignment .getWidth(), hconsensus, true); updateAnnotation(true); if (globalColourScheme != null) { globalColourScheme.setConsensus(hconsensus); } } catch (OutOfMemoryError error) { alignment.deleteAnnotation(consensus); consensus = null; hconsensus = null; new OOMWarning("calculating consensus", error); } UPDATING_CONSENSUS = false; updatingConsensus = false; if (ap != null) { ap.paintAlignment(true); } } /** * update the consensus annotation from the sequence profile data using * current visualization settings. */ public void updateAnnotation() { updateAnnotation(false); } protected void updateAnnotation(boolean immediate) { // TODO: make calls thread-safe, so if another thread calls this method, // it will either return or wait until one calculation is finished. if (immediate || (!updatingConsensus && consensus != null && hconsensus != null)) { AAFrequency.completeConsensus(consensus, hconsensus, 0, hconsensus.length, ignoreGapsInConsensusCalculation, showSequenceLogo); } } } // --------START Structure Conservation public void updateStrucConsensus(final AlignmentPanel ap) { // see note in mantis : issue number 8585 if (strucConsensus == null || !autoCalculateStrucConsensus) { return; } strucConsensusThread = new StrucConsensusThread(ap); strucConsensusThread.start(); } class StrucConsensusThread extends Thread { AlignmentPanel ap; public StrucConsensusThread(AlignmentPanel ap) { this.ap = ap; } public void run() { updatingStrucConsensus = true; while (UPDATING_STRUC_CONSENSUS) { try { if (ap != null) { ap.paintAlignment(false); } Thread.sleep(200); } catch (Exception ex) { ex.printStackTrace(); } } UPDATING_STRUC_CONSENSUS = true; try { int aWidth = (alignment != null) ? alignment.getWidth() : -1; // null // pointer // possibility // here. if (aWidth <= 0) { updatingStrucConsensus = false; UPDATING_STRUC_CONSENSUS = false; return; } strucConsensus.annotations = null; strucConsensus.annotations = new Annotation[aWidth]; hStrucConsensus = new Hashtable[aWidth]; AlignmentAnnotation[] aa = ap.av.getAlignment() .getAlignmentAnnotation(); AlignmentAnnotation rnaStruc = null; for (int i = 0; i < aa.length; i++) { if (aa[i].getRNAStruc() != null) { rnaStruc = aa[i]; break; } } AlignmentAnnotation rna = ap.av.getAlignment() .getAlignmentAnnotation()[0]; StructureFrequency.calculate(alignment.getSequencesArray(), 0, alignment.getWidth(), hStrucConsensus, true, rnaStruc); // TODO AlignmentAnnotation rnaStruc!!! updateAnnotation(true); if (globalColourScheme != null) { globalColourScheme.setConsensus(hStrucConsensus); } } catch (OutOfMemoryError error) { alignment.deleteAnnotation(strucConsensus); strucConsensus = null; hStrucConsensus = null; new OOMWarning("calculating structure consensus", error); } UPDATING_STRUC_CONSENSUS = false; updatingStrucConsensus = false; if (ap != null) { ap.paintAlignment(true); } } /** * update the consensus annotation from the sequence profile data using * current visualization settings. */ public void updateAnnotation() { updateAnnotation(false); } protected void updateAnnotation(boolean immediate) { // TODO: make calls thread-safe, so if another thread calls this method, // it will either return or wait until one calculation is finished. if (immediate || (!updatingStrucConsensus && strucConsensus != null && hStrucConsensus != null)) { StructureFrequency.completeConsensus(strucConsensus, hStrucConsensus, 0, hStrucConsensus.length, false, showSequenceLogo); } } } // --------END Structure Conservation /** * 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++) { if (consensus.annotations[i] != null) { if (consensus.annotations[i].description.charAt(0) == '[') { seqs.append(consensus.annotations[i].description.charAt(1)); } else { seqs.append(consensus.annotations[i].displayCharacter); } } } SequenceI sq = new Sequence("Consensus", seqs.toString()); sq.setDescription("Percentage Identity Consensus " + ((ignoreGapsInConsensusCalculation) ? " without gaps" : "")); return sq; } /** * * * @return null or the currently selected sequence region */ public SequenceGroup getSelectionGroup() { return selectionGroup; } /** * Set the selection group for this window. * * @param sg * - group holding references to sequences in this alignment view * */ public void setSelectionGroup(SequenceGroup sg) { selectionGroup = sg; } /** * GUI state * * @return true if conservation based shading is enabled */ public boolean getConservationSelected() { return conservationColourSelected; } /** * GUI state * * @param b * enable conservation based shading */ public void setConservationSelected(boolean b) { conservationColourSelected = b; } /** * GUI state * * @return true if percent identity threshold is applied to shading */ public boolean getAbovePIDThreshold() { return abovePIDThreshold; } /** * GUI state * * * @param b * indicate if percent identity threshold is applied to shading */ public void setAbovePIDThreshold(boolean b) { abovePIDThreshold = b; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public int getStartRes() { return startRes; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public int getEndRes() { return endRes; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public int getStartSeq() { return startSeq; } /** * DOCUMENT ME! * * @param cs * DOCUMENT ME! */ public void setGlobalColourScheme(ColourSchemeI cs) { globalColourScheme = cs; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public ColourSchemeI getGlobalColourScheme() { return globalColourScheme; } /** * DOCUMENT ME! * * @param res * DOCUMENT ME! */ public void setStartRes(int res) { this.startRes = res; } /** * DOCUMENT ME! * * @param seq * DOCUMENT ME! */ public void setStartSeq(int seq) { this.startSeq = seq; } /** * DOCUMENT ME! * * @param res * DOCUMENT ME! */ public void setEndRes(int res) { if (res > (alignment.getWidth() - 1)) { // log.System.out.println(" Corrected res from " + res + " to maximum " + // (alignment.getWidth()-1)); res = alignment.getWidth() - 1; } if (res < 0) { res = 0; } this.endRes = res; } /** * DOCUMENT ME! * * @param seq * DOCUMENT ME! */ public void setEndSeq(int seq) { if (seq > alignment.getHeight()) { seq = alignment.getHeight(); } if (seq < 0) { seq = 0; } this.endSeq = seq; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public int getEndSeq() { return endSeq; } /** * DOCUMENT ME! * * @param f * DOCUMENT ME! */ public void setFont(Font f) { font = f; Container c = new Container(); java.awt.FontMetrics fm = c.getFontMetrics(font); setCharHeight(fm.getHeight()); setCharWidth(fm.charWidth('M')); validCharWidth = true; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public Font getFont() { return font; } /** * DOCUMENT ME! * * @param w * DOCUMENT ME! */ public void setCharWidth(int w) { this.charWidth = w; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public int getCharWidth() { return charWidth; } /** * DOCUMENT ME! * * @param h * DOCUMENT ME! */ public void setCharHeight(int h) { this.charHeight = h; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public int getCharHeight() { return charHeight; } /** * DOCUMENT ME! * * @param w * DOCUMENT ME! */ public void setWrappedWidth(int w) { this.wrappedWidth = w; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public int getWrappedWidth() { return wrappedWidth; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public AlignmentI getAlignment() { return alignment; } /** * DOCUMENT ME! * * @param align * DOCUMENT ME! */ public void setAlignment(AlignmentI align) { if (alignment != null && alignment.getCodonFrames() != null) { StructureSelectionManager.getStructureSelectionManager( Desktop.instance).removeMappings(alignment.getCodonFrames()); } this.alignment = align; if (alignment.getCodonFrames() != null) { StructureSelectionManager.getStructureSelectionManager( Desktop.instance).addMappings(alignment.getCodonFrames()); } } /** * DOCUMENT ME! * * @param state * DOCUMENT ME! */ public void setWrapAlignment(boolean state) { wrapAlignment = state; } /** * DOCUMENT ME! * * @param state * DOCUMENT ME! */ public void setShowText(boolean state) { showText = state; } /** * DOCUMENT ME! * * @param state * DOCUMENT ME! */ public void setRenderGaps(boolean state) { renderGaps = state; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public boolean getColourText() { return showColourText; } /** * DOCUMENT ME! * * @param state * DOCUMENT ME! */ public void setColourText(boolean state) { showColourText = state; } /** * DOCUMENT ME! * * @param state * DOCUMENT ME! */ public void setShowBoxes(boolean state) { showBoxes = state; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public boolean getWrapAlignment() { return wrapAlignment; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public boolean getShowText() { return showText; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public boolean getShowBoxes() { return showBoxes; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public char getGapCharacter() { return getAlignment().getGapCharacter(); } /** * DOCUMENT ME! * * @param gap * DOCUMENT ME! */ public void setGapCharacter(char gap) { if (getAlignment() != null) { getAlignment().setGapCharacter(gap); } } /** * DOCUMENT ME! * * @param thresh * DOCUMENT ME! */ public void setThreshold(int thresh) { threshold = thresh; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public int getThreshold() { return threshold; } /** * DOCUMENT ME! * * @param inc * DOCUMENT ME! */ public void setIncrement(int inc) { increment = inc; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public int getIncrement() { return increment; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public ColumnSelection getColumnSelection() { return colSel; } /** * DOCUMENT ME! * * @param tree * DOCUMENT ME! */ public void setCurrentTree(NJTree tree) { currentTree = tree; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public NJTree getCurrentTree() { return currentTree; } /** * DOCUMENT ME! * * @param b * DOCUMENT ME! */ public void setColourAppliesToAllGroups(boolean b) { colourAppliesToAllGroups = b; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public boolean getColourAppliesToAllGroups() { return colourAppliesToAllGroups; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public boolean getShowJVSuffix() { return showJVSuffix; } /** * DOCUMENT ME! * * @param b * DOCUMENT ME! */ public void setShowJVSuffix(boolean b) { showJVSuffix = b; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public boolean getShowAnnotation() { return showAnnotation; } /** * DOCUMENT ME! * * @param b * DOCUMENT ME! */ public void setShowAnnotation(boolean b) { showAnnotation = b; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public boolean getScaleAboveWrapped() { return scaleAboveWrapped; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public boolean getScaleLeftWrapped() { return scaleLeftWrapped; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public boolean getScaleRightWrapped() { return scaleRightWrapped; } /** * DOCUMENT ME! * * @param b * DOCUMENT ME! */ public void setScaleAboveWrapped(boolean b) { scaleAboveWrapped = b; } /** * DOCUMENT ME! * * @param b * DOCUMENT ME! */ public void setScaleLeftWrapped(boolean b) { scaleLeftWrapped = b; } /** * DOCUMENT ME! * * @param b * DOCUMENT ME! */ public void setScaleRightWrapped(boolean b) { scaleRightWrapped = b; } /** * Property change listener for changes in alignment * * @param listener * DOCUMENT ME! */ public void addPropertyChangeListener( java.beans.PropertyChangeListener listener) { changeSupport.addPropertyChangeListener(listener); } /** * DOCUMENT ME! * * @param listener * DOCUMENT ME! */ public void removePropertyChangeListener( java.beans.PropertyChangeListener listener) { changeSupport.removePropertyChangeListener(listener); } /** * Property change listener for changes in alignment * * @param prop * DOCUMENT ME! * @param oldvalue * DOCUMENT ME! * @param newvalue * DOCUMENT ME! */ public void firePropertyChange(String prop, Object oldvalue, Object newvalue) { changeSupport.firePropertyChange(prop, oldvalue, newvalue); } public void setIgnoreGapsConsensus(boolean b, AlignmentPanel ap) { ignoreGapsInConsensusCalculation = b; updateConsensus(ap); if (globalColourScheme != null) { globalColourScheme.setThreshold(globalColourScheme.getThreshold(), ignoreGapsInConsensusCalculation); } } public boolean getIgnoreGapsConsensus() { return ignoreGapsInConsensusCalculation; } public void setDataset(boolean b) { isDataset = b; } public boolean isDataset() { return isDataset; } public void hideSelectedColumns() { if (colSel.size() < 1) { return; } colSel.hideSelectedColumns(); setSelectionGroup(null); hasHiddenColumns = true; } public void hideColumns(int start, int end) { if (start == end) { colSel.hideColumns(start); } else { colSel.hideColumns(start, end); } hasHiddenColumns = true; } public void hideRepSequences(SequenceI repSequence, SequenceGroup sg) { int sSize = sg.getSize(); if (sSize < 2) { return; } if (hiddenRepSequences == null) { hiddenRepSequences = new Hashtable(); } hiddenRepSequences.put(repSequence, sg); // Hide all sequences except the repSequence SequenceI[] seqs = new SequenceI[sSize - 1]; int index = 0; for (int i = 0; i < sSize; i++) { if (sg.getSequenceAt(i) != repSequence) { if (index == sSize - 1) { return; } seqs[index++] = sg.getSequenceAt(i); } } sg.setSeqrep(repSequence); sg.setHidereps(true); hideSequence(seqs); } public void hideAllSelectedSeqs() { if (selectionGroup == null || selectionGroup.getSize() < 1) { return; } SequenceI[] seqs = selectionGroup.getSequencesInOrder(alignment); hideSequence(seqs); setSelectionGroup(null); } public void hideSequence(SequenceI[] seq) { if (seq != null) { for (int i = 0; i < seq.length; i++) { alignment.getHiddenSequences().hideSequence(seq[i]); } hasHiddenRows = true; firePropertyChange("alignment", null, alignment.getSequences()); } } public void showSequence(int index) { Vector tmp = alignment.getHiddenSequences().showSequence(index, hiddenRepSequences); if (tmp.size() > 0) { if (selectionGroup == null) { selectionGroup = new SequenceGroup(); selectionGroup.setEndRes(alignment.getWidth() - 1); } for (int t = 0; t < tmp.size(); t++) { selectionGroup.addSequence((SequenceI) tmp.elementAt(t), false); } firePropertyChange("alignment", null, alignment.getSequences()); sendSelection(); } if (alignment.getHiddenSequences().getSize() < 1) { hasHiddenRows = false; } } public void showColumn(int col) { colSel.revealHiddenColumns(col); if (colSel.getHiddenColumns() == null) { hasHiddenColumns = false; } } public void showAllHiddenColumns() { colSel.revealAllHiddenColumns(); hasHiddenColumns = false; } public void showAllHiddenSeqs() { if (alignment.getHiddenSequences().getSize() > 0) { if (selectionGroup == null) { selectionGroup = new SequenceGroup(); selectionGroup.setEndRes(alignment.getWidth() - 1); } Vector tmp = alignment.getHiddenSequences().showAll( hiddenRepSequences); for (int t = 0; t < tmp.size(); t++) { selectionGroup.addSequence((SequenceI) tmp.elementAt(t), false); } firePropertyChange("alignment", null, alignment.getSequences()); sendSelection(); hasHiddenRows = false; hiddenRepSequences = null; } } public void invertColumnSelection() { colSel.invertColumnSelection(0, alignment.getWidth()); } public int adjustForHiddenSeqs(int alignmentIndex) { return alignment.getHiddenSequences().adjustForHiddenSeqs( alignmentIndex); } /** * This method returns an array of new SequenceI objects derived from the * whole alignment or just the current selection with start and end points * adjusted * * @note if you need references to the actual SequenceI objects in the * alignment or currently selected then use getSequenceSelection() * @return selection as new sequenceI objects */ public SequenceI[] getSelectionAsNewSequence() { SequenceI[] sequences; if (selectionGroup == null) { sequences = alignment.getSequencesArray(); 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 } } else { sequences = selectionGroup.getSelectionAsNewSequences(alignment); } return sequences; } /** * get the currently selected sequence objects or all the sequences in the * alignment. * * @return array of references to sequence objects */ public SequenceI[] getSequenceSelection() { SequenceI[] sequences = null; if (selectionGroup != null) { sequences = selectionGroup.getSequencesInOrder(alignment); } if (sequences == null) { sequences = alignment.getSequencesArray(); } return sequences; } /** * This method returns the visible alignment as text, as seen on the GUI, ie * if columns are hidden they will not be returned in the result. Use this for * calculating trees, PCA, redundancy etc on views which contain hidden * columns. * * @return String[] */ public jalview.datamodel.CigarArray getViewAsCigars( boolean selectedRegionOnly) { return new jalview.datamodel.CigarArray(alignment, (hasHiddenColumns ? colSel : null), (selectedRegionOnly ? selectionGroup : null)); } /** * return a compact representation of the current alignment selection to pass * to an analysis function * * @param selectedOnly * boolean true to just return the selected view * @return AlignmentView */ public jalview.datamodel.AlignmentView getAlignmentView( boolean selectedOnly) { return getAlignmentView(selectedOnly, false); } /** * return a compact representation of the current alignment selection to pass * to an analysis function * * @param selectedOnly * boolean true to just return the selected view * @param markGroups * boolean true to annotate the alignment view with groups on the * alignment (and intersecting with selected region if selectedOnly * is true) * @return AlignmentView */ public jalview.datamodel.AlignmentView getAlignmentView( boolean selectedOnly, boolean markGroups) { return new AlignmentView(alignment, colSel, selectionGroup, hasHiddenColumns, selectedOnly, markGroups); } /** * This method returns the visible alignment as text, as seen on the GUI, ie * if columns are hidden they will not be returned in the result. Use this for * calculating trees, PCA, redundancy etc on views which contain hidden * columns. * * @return String[] */ public String[] getViewAsString(boolean selectedRegionOnly) { String[] selection = null; SequenceI[] seqs = null; int i, iSize; int start = 0, end = 0; if (selectedRegionOnly && selectionGroup != null) { iSize = selectionGroup.getSize(); seqs = selectionGroup.getSequencesInOrder(alignment); start = selectionGroup.getStartRes(); end = selectionGroup.getEndRes() + 1; } else { iSize = alignment.getHeight(); seqs = alignment.getSequencesArray(); end = alignment.getWidth(); } selection = new String[iSize]; if (hasHiddenColumns) { selection = colSel.getVisibleSequenceStrings(start, end, seqs); } else { for (i = 0; i < iSize; i++) { selection[i] = seqs[i].getSequenceAsString(start, end); } } return selection; } public int[][] getVisibleRegionBoundaries(int min, int max) { Vector regions = new Vector(); int start = min; int end = max; do { if (hasHiddenColumns) { if (start == 0) { start = colSel.adjustForHiddenColumns(start); } end = colSel.getHiddenBoundaryRight(start); if (start == end) { end = max; } if (end > max) { end = max; } } regions.addElement(new int[] { start, end }); if (hasHiddenColumns) { start = colSel.adjustForHiddenColumns(end); start = colSel.getHiddenBoundaryLeft(start) + 1; } } while (end < max); int[][] startEnd = new int[regions.size()][2]; regions.copyInto(startEnd); return startEnd; } public boolean getShowHiddenMarkers() { return showHiddenMarkers; } public void setShowHiddenMarkers(boolean show) { showHiddenMarkers = show; } public String getSequenceSetId() { if (sequenceSetID == null) { sequenceSetID = alignment.hashCode() + ""; } return sequenceSetID; } /** * unique viewId for synchronizing state with stored Jalview Project * */ private String viewId = null; public String getViewId() { if (viewId == null) { viewId = this.getSequenceSetId() + "." + this.hashCode() + ""; } return viewId; } public void alignmentChanged(AlignmentPanel ap) { if (padGaps) { alignment.padGaps(); } if (hconsensus != null && autoCalculateConsensus) { updateConservation(ap); } if (autoCalculateConsensus) { updateConsensus(ap); } if (autoCalculateStrucConsensus) { updateStrucConsensus(ap); } // Reset endRes of groups if beyond alignment width int alWidth = alignment.getWidth(); Vector groups = alignment.getGroups(); if (groups != null) { for (int i = 0; i < groups.size(); i++) { SequenceGroup sg = (SequenceGroup) groups.elementAt(i); if (sg.getEndRes() > alWidth) { sg.setEndRes(alWidth - 1); } } } if (selectionGroup != null && selectionGroup.getEndRes() > alWidth) { selectionGroup.setEndRes(alWidth - 1); } resetAllColourSchemes(); // alignment.adjustSequenceAnnotations(); } void resetAllColourSchemes() { ColourSchemeI cs = globalColourScheme; if (cs != null) { if (cs instanceof ClustalxColourScheme) { ((ClustalxColourScheme) cs).resetClustalX(alignment.getSequences(), alignment.getWidth()); } cs.setConsensus(hconsensus); if (cs.conservationApplied()) { Alignment al = (Alignment) alignment; Conservation c = new Conservation("All", ResidueProperties.propHash, 3, al.getSequences(), 0, al .getWidth() - 1); c.calculate(); c.verdict(false, ConsPercGaps); cs.setConservation(c); } } int s, sSize = alignment.getGroups().size(); for (s = 0; s < sSize; s++) { SequenceGroup sg = (SequenceGroup) alignment.getGroups().elementAt(s); if (sg.cs != null && sg.cs instanceof ClustalxColourScheme) { ((ClustalxColourScheme) sg.cs).resetClustalX(sg .getSequences(hiddenRepSequences), sg.getWidth()); } sg.recalcConservation(); } } public Color getSequenceColour(SequenceI seq) { if (sequenceColours == null || !sequenceColours.containsKey(seq)) { return Color.white; } else { return (Color) sequenceColours.get(seq); } } public void setSequenceColour(SequenceI seq, Color col) { if (sequenceColours == null) { sequenceColours = new Hashtable(); } if (col == null) { sequenceColours.remove(seq); } else { sequenceColours.put(seq, col); } } /** * returns the visible column regions of the alignment * * @param selectedRegionOnly * true to just return the contigs intersecting with the selected * area * @return */ public int[] getViewAsVisibleContigs(boolean selectedRegionOnly) { int[] viscontigs = null; int start = 0, end = 0; if (selectedRegionOnly && selectionGroup != null) { start = selectionGroup.getStartRes(); end = selectionGroup.getEndRes() + 1; } else { end = alignment.getWidth(); } viscontigs = colSel.getVisibleContigs(start, end); return viscontigs; } /** * get hash of undo and redo list for the alignment * * @return long[] { historyList.hashCode, redoList.hashCode }; */ public long[] getUndoRedoHash() { if (historyList == null || redoList == null) return new long[] { -1, -1 }; return new long[] { historyList.hashCode(), this.redoList.hashCode() }; } /** * test if a particular set of hashcodes are different to the hashcodes for * the undo and redo list. * * @param undoredo * the stored set of hashcodes as returned by getUndoRedoHash * @return true if the hashcodes differ (ie the alignment has been edited) or * the stored hashcode array differs in size */ public boolean isUndoRedoHashModified(long[] undoredo) { if (undoredo == null) { return true; } long[] cstate = getUndoRedoHash(); if (cstate.length != undoredo.length) { return true; } for (int i = 0; i < cstate.length; i++) { if (cstate[i] != undoredo[i]) { return true; } } return false; } public boolean getCentreColumnLabels() { return centreColumnLabels; } public void setCentreColumnLabels(boolean centrecolumnlabels) { centreColumnLabels = centrecolumnlabels; } public void updateSequenceIdColours() { Vector groups = alignment.getGroups(); if (sequenceColours == null) { sequenceColours = new Hashtable(); } for (int ig = 0, igSize = groups.size(); ig < igSize; ig++) { SequenceGroup sg = (SequenceGroup) groups.elementAt(ig); if (sg.idColour != null) { Vector sqs = sg.getSequences(hiddenRepSequences); for (int s = 0, sSize = sqs.size(); s < sSize; s++) { sequenceColours.put(sqs.elementAt(s), sg.idColour); } } } } /** * enable or disable the display of Database Cross References in the sequence * ID tooltip */ public void setShowDbRefs(boolean show) { showdbrefs = show; } /** * * @return true if Database References are to be displayed on tooltips. */ public boolean isShowDbRefs() { return showdbrefs; } /** * * @return true if Non-positional features are to be displayed on tooltips. */ public boolean isShowNpFeats() { return shownpfeats; } /** * enable or disable the display of Non-Positional sequence features in the * sequence ID tooltip * * @param show */ public void setShowNpFeats(boolean show) { shownpfeats = show; } /** * * @return true if view has hidden rows */ public boolean hasHiddenRows() { return hasHiddenRows; } /** * * @return true if view has hidden columns */ public boolean hasHiddenColumns() { return hasHiddenColumns; } /** * when set, view will scroll to show the highlighted position */ public boolean followHighlight = true; /** * @return true if view should scroll to show the highlighted region of a * sequence * @return */ public boolean getFollowHighlight() { return followHighlight; } public boolean followSelection = true; /** * @return true if view selection should always follow the selections * broadcast by other selection sources */ public boolean getFollowSelection() { return followSelection; } private long sgrouphash = -1, colselhash = -1; boolean showSeqFeaturesHeight; /** * checks current SelectionGroup against record of last hash value, and * updates record. * * @param b * update the record of last hash value * * @return true if SelectionGroup changed since last call (when b is true) */ boolean isSelectionGroupChanged(boolean b) { int hc = (selectionGroup == null || selectionGroup.getSize() == 0) ? -1 : selectionGroup.hashCode(); if (hc != -1 && hc != sgrouphash) { if (b) { sgrouphash = hc; } return true; } return false; } /** * checks current colsel against record of last hash value, and optionally * updates record. * * @param b * update the record of last hash value * @return true if colsel changed since last call (when b is true) */ boolean isColSelChanged(boolean b) { int hc = (colSel == null || colSel.size() == 0) ? -1 : colSel .hashCode(); if (hc != -1 && hc != colselhash) { if (b) { colselhash = hc; } return true; } return false; } public void sendSelection() { jalview.structure.StructureSelectionManager .getStructureSelectionManager(Desktop.instance).sendSelection( new SequenceGroup(getSelectionGroup()), new ColumnSelection(getColumnSelection()), this); } public void setShowSequenceFeaturesHeight(boolean selected) { showSeqFeaturesHeight = selected; } public boolean getShowSequenceFeaturesHeight() { return showSeqFeaturesHeight; } boolean showUnconserved = false; public boolean getShowUnconserved() { return showUnconserved; } public void setShowUnconserved(boolean showunconserved) { showUnconserved = showunconserved; } /** * return the alignPanel containing the given viewport. Use this to get the * components currently handling the given viewport. * * @param av * @return null or an alignPanel guaranteed to have non-null alignFrame * reference */ public AlignmentPanel getAlignPanel() { AlignmentPanel[] aps = PaintRefresher.getAssociatedPanels(this .getSequenceSetId()); AlignmentPanel ap = null; for (int p = 0; aps != null && p < aps.length; p++) { if (aps[p].av == this) { return aps[p]; } } return null; } public boolean getSortByTree() { return sortByTree; } public void setSortByTree(boolean sort) { sortByTree = sort; } /** * should conservation rows be shown for groups */ boolean showGroupConservation = false; /** * should consensus rows be shown for groups */ boolean showGroupConsensus = false; /** * should consensus profile be rendered by default */ public boolean showSequenceLogo = false; /** * should consensus histograms be rendered by default */ public boolean showConsensusHistogram = true; /** * @return the showConsensusProfile */ public boolean isShowSequenceLogo() { return showSequenceLogo; } /** * @param showSequenceLogo * the new value */ public void setShowSequenceLogo(boolean showSequenceLogo) { if (showSequenceLogo != this.showSequenceLogo) { // TODO: decouple settings setting from calculation when refactoring // annotation update method from alignframe to viewport this.showSequenceLogo = showSequenceLogo; if (consensusThread != null) { consensusThread.updateAnnotation(); } if (strucConsensusThread != null) { strucConsensusThread.updateAnnotation(); } } this.showSequenceLogo = showSequenceLogo; } /** * @param showConsensusHistogram * the showConsensusHistogram to set */ public void setShowConsensusHistogram(boolean showConsensusHistogram) { this.showConsensusHistogram = showConsensusHistogram; } /** * @return the showGroupConservation */ public boolean isShowGroupConservation() { return showGroupConservation; } /** * @param showGroupConservation * the showGroupConservation to set */ public void setShowGroupConservation(boolean showGroupConservation) { this.showGroupConservation = showGroupConservation; } /** * @return the showGroupConsensus */ public boolean isShowGroupConsensus() { return showGroupConsensus; } /** * @param showGroupConsensus * the showGroupConsensus to set */ public void setShowGroupConsensus(boolean showGroupConsensus) { this.showGroupConsensus = showGroupConsensus; } /** * * @return flag to indicate if the consensus histogram should be rendered by * default */ public boolean isShowConsensusHistogram() { return this.showConsensusHistogram; } /** * 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()) && (colSel == null || colSel.getSelected() == null || colSel .getSelected().size() == 0)) { 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); } } } public StructureSelectionManager getStructureSelectionManager() { return StructureSelectionManager .getStructureSelectionManager(Desktop.instance); } /** * * @param pdbEntries * @return a series of SequenceI arrays, one for each PDBEntry, listing which * sequence in the alignment holds a reference to it */ public SequenceI[][] collateForPDB(PDBEntry[] pdbEntries) { ArrayList seqvectors = new ArrayList(); for (PDBEntry pdb : pdbEntries) { ArrayList seqs = new ArrayList(); for (int i = 0; i < alignment.getHeight(); i++) { Vector pdbs = alignment.getSequenceAt(i).getDatasetSequence() .getPDBId(); if (pdbs == null) continue; SequenceI sq; for (int p = 0; p < pdbs.size(); p++) { PDBEntry p1 = (PDBEntry) pdbs.elementAt(p); if (p1.getId().equals(pdb.getId())) { if (!seqs.contains(sq = alignment.getSequenceAt(i))) seqs.add(sq); continue; } } } seqvectors.add(seqs.toArray(new SequenceI[seqs.size()])); } return seqvectors.toArray(new SequenceI[seqvectors.size()][]); } }