/* * Jalview - A Sequence Alignment Editor and Viewer * Copyright (C) 2005 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 jalview.analysis.*; import jalview.bin.*; import jalview.datamodel.*; import jalview.schemes.*; import java.awt.*; import java.util.*; /** * DOCUMENT ME! * * @author $author$ * @version $Revision$ */ public class AlignViewport { 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 showConservation = true; boolean showQuality = true; boolean showIdentity = true; boolean colourAppliesToAllGroups = true; ColourSchemeI globalColourScheme = null; boolean conservationColourSelected = false; boolean abovePIDThreshold = false; SequenceGroup selectionGroup; int charHeight; int charWidth; int wrappedWidth; Font font = new Font("SansSerif", Font.PLAIN, 10); AlignmentI alignment; ColumnSelection colSel = new ColumnSelection(); int threshold; int increment; NJTree currentTree = null; boolean scaleAboveWrapped = false; boolean scaleLeftWrapped = true; boolean scaleRightWrapped = true; /** DOCUMENT ME!! */ public Vector vconsensus; AlignmentAnnotation consensus; AlignmentAnnotation conservation; AlignmentAnnotation quality; /** 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; public AlignViewport(AlignmentI al, boolean dataset) { isDataset = dataset; setAlignment(al); init(); } /** * Creates a new AlignViewport object. * * @param al DOCUMENT ME! */ public AlignViewport(AlignmentI al) { setAlignment(al); init(); } void init() { this.startRes = 0; this.endRes = alignment.getWidth() - 1; this.startSeq = 0; this.endSeq = alignment.getHeight() - 1; showJVSuffix = Cache.getDefault("SHOW_JVSUFFIX", true); showAnnotation = Cache.getDefault("SHOW_ANNOTATIONS", true); showConservation = Cache.getDefault("SHOW_CONSERVATION", true); showQuality = Cache.getDefault("SHOW_QUALITY", true); showIdentity = Cache.getDefault("SHOW_IDENTITY", true); String fontName = Cache.getDefault("FONT_NAME", "SansSerif"); String fontStyle = Cache.getDefault("FONT_STYLE", Font.PLAIN + "") ; String fontSize = Cache.getDefault("FONT_SIZE", "10"); 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(vconsensus==null && !isDataset) { updateConservation(); updateConsensus(); } 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(vconsensus); } } } /** * DOCUMENT ME! * * @param b DOCUMENT ME! */ public void showSequenceFeatures(boolean b) { showSequenceFeatures = b; } /** * DOCUMENT ME! */ public void updateConservation() { if(alignment.isNucleotide()) return; try{ Conservation cons = new jalview.analysis.Conservation("All", jalview.schemes.ResidueProperties.propHash, 3, alignment.getSequences(), 0, alignment.getWidth() - 1); cons.calculate(); cons.verdict(false, ConsPercGaps); cons.findQuality(); int alWidth = alignment.getWidth(); Annotation[] annotations = new Annotation[alWidth]; Annotation[] qannotations = new Annotation[alWidth]; String sequence = cons.getConsSequence().getSequence(); float minR; float minG; float minB; float maxR; float maxG; float maxB; minR = 0.3f; minG = 0.0f; minB = 0f; maxR = 1.0f - minR; maxG = 0.9f - minG; maxB = 0f - minB; // scalable range for colouring both Conservation and Quality float min = 0f; float max = 11f; float qmin = cons.qualityRange[0].floatValue(); float qmax = cons.qualityRange[1].floatValue(); for (int i = 0; i < alWidth; i++) { float value = 0; try { value = Integer.parseInt(sequence.charAt(i) + ""); } catch (Exception ex) { if (sequence.charAt(i) == '*') { value = 11; } if (sequence.charAt(i) == '+') { value = 10; } } float vprop = value - min; vprop /= max; annotations[i] = new Annotation(sequence.charAt(i) + "", String.valueOf(value), ' ', value, new Color(minR + (maxR * vprop), minG + (maxG * vprop), minB + (maxB * vprop))); // Quality calc value = ( (Double) cons.quality.get(i)).floatValue(); vprop = value - qmin; vprop /= qmax; qannotations[i] = new Annotation(" ", String.valueOf(value), ' ', value, new Color(minR + (maxR * vprop), minG + (maxG * vprop), minB + (maxB * vprop))); } if (conservation == null) { conservation = new AlignmentAnnotation("Conservation", "Conservation of total alignment less than " + ConsPercGaps + "% gaps", annotations, 0f, // cons.qualityRange[0].floatValue(), 11f, // cons.qualityRange[1].floatValue() 1); if (showConservation) { alignment.addAnnotation(conservation); } quality = new AlignmentAnnotation("Quality", "Alignment Quality based on Blosum62 scores", qannotations, cons.qualityRange[0].floatValue(), cons.qualityRange[1].floatValue(), 1); if (showQuality) { alignment.addAnnotation(quality); } } else { conservation.annotations = annotations; quality.annotations = qannotations; quality.graphMax = cons.qualityRange[1].floatValue(); } } catch (OutOfMemoryError error) { javax.swing.JOptionPane.showInternalMessageDialog(Desktop.desktop, "Out of memory calculating conservation!!" + "\nSee help files for increasing Java Virtual Machine memory." , "Out of memory", javax.swing.JOptionPane.WARNING_MESSAGE); System.out.println("Conservation calculation: " + error); System.gc(); } } /** * DOCUMENT ME! */ public void updateConsensus() { try{ Annotation[] annotations = new Annotation[alignment.getWidth()]; // this routine prevents vconsensus becoming a new object each time // consenus is calculated. Important for speed of Blosum62 // and PID colouring of alignment if (vconsensus == null) { vconsensus = alignment.getAAFrequency(); } else { Vector temp = alignment.getAAFrequency(); vconsensus.clear(); Enumeration e = temp.elements(); while (e.hasMoreElements()) { vconsensus.add(e.nextElement()); } } Hashtable hash = null; for (int i = 0; i < alignment.getWidth(); i++) { hash = (Hashtable) vconsensus.elementAt(i); float value = 0; if (ignoreGapsInConsensusCalculation) value = ( (Float) hash.get("pid_nogaps")).floatValue(); else value = ( (Float) hash.get("pid_gaps")).floatValue(); String maxRes = hash.get("maxResidue").toString(); String mouseOver = hash.get("maxResidue") + " "; if (maxRes.length() > 1) { mouseOver = "[" + maxRes + "] "; maxRes = "+"; } mouseOver += ( (int) value + "%"); annotations[i] = new Annotation(maxRes, mouseOver, ' ', value); } if (consensus == null) { consensus = new AlignmentAnnotation("Consensus", "PID", annotations, 0f, 100f, 1); if (showIdentity) { alignment.addAnnotation(consensus); } } else { consensus.annotations = annotations; } if (globalColourScheme != null) globalColourScheme.setConsensus(vconsensus); }catch(OutOfMemoryError error) { javax.swing.JOptionPane.showInternalMessageDialog(Desktop.desktop, "Out of memory calculating consensus!!" + "\nSee help files for increasing Java Virtual Machine memory." , "Out of memory", javax.swing.JOptionPane.WARNING_MESSAGE); System.out.println("Consensus calculation: " + error); System.gc(); } } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public SequenceGroup getSelectionGroup() { return selectionGroup; } /** * DOCUMENT ME! * * @param sg DOCUMENT ME! */ public void setSelectionGroup(SequenceGroup sg) { selectionGroup = sg; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public boolean getConservationSelected() { return conservationColourSelected; } /** * DOCUMENT ME! * * @param b DOCUMENT ME! */ public void setConservationSelected(boolean b) { conservationColourSelected = b; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public boolean getAbovePIDThreshold() { return abovePIDThreshold; } /** * DOCUMENT ME! * * @param b DOCUMENT ME! */ 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')); } /** * 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) { this.alignment = align; } /** * 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! * * @param y DOCUMENT ME! * * @return DOCUMENT ME! */ public int getIndex(int y) { int y1 = 0; int starty = getStartSeq(); int endy = getEndSeq(); for (int i = starty; i <= endy; i++) { if ((i < alignment.getHeight()) && (alignment.getSequenceAt(i) != null)) { int y2 = y1 + getCharHeight(); if ((y >= y1) && (y <= y2)) { return i; } y1 = y2; } else { return -1; } } return -1; } /** * 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) { ignoreGapsInConsensusCalculation = b; updateConsensus(); 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; } }