2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.6)
3 * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
11 * Jalview is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with Jalview. If not, see <http://www.gnu.org/licenses/>.
18 package jalview.appletgui;
24 import jalview.analysis.*;
26 import jalview.datamodel.*;
27 import jalview.schemes.*;
28 import jalview.structure.SelectionSource;
29 import jalview.structure.StructureSelectionManager;
30 import jalview.structure.VamsasSource;
32 public class AlignViewport implements SelectionSource, VamsasSource
42 boolean cursorMode = false;
44 boolean showJVSuffix = true;
46 boolean showText = true;
48 boolean showColourText = false;
50 boolean showBoxes = true;
52 boolean wrapAlignment = false;
54 boolean renderGaps = true;
56 boolean showSequenceFeatures = false;
58 boolean showAnnotation = true;
60 boolean showConservation = true;
62 boolean showQuality = true;
64 boolean showConsensus = true;
66 boolean upperCasebold = false;
68 boolean colourAppliesToAllGroups = true;
70 ColourSchemeI globalColourScheme = null;
72 boolean conservationColourSelected = false;
74 boolean abovePIDThreshold = false;
76 SequenceGroup selectionGroup;
84 Font font = new Font("SansSerif", Font.PLAIN, 10);
86 boolean validCharWidth = true;
90 ColumnSelection colSel = new ColumnSelection();
96 NJTree currentTree = null;
98 boolean scaleAboveWrapped = true;
100 boolean scaleLeftWrapped = true;
102 boolean scaleRightWrapped = true;
104 // The following vector holds the features which are
105 // currently visible, in the correct order or rendering
106 public Hashtable featuresDisplayed;
108 boolean hasHiddenColumns = false;
110 boolean hasHiddenRows = false;
112 boolean showHiddenMarkers = true;
114 public Hashtable[] hconsensus;
116 AlignmentAnnotation consensus;
118 AlignmentAnnotation conservation;
120 AlignmentAnnotation quality;
122 AlignmentAnnotation[] groupConsensus;
124 AlignmentAnnotation[] groupConservation;
126 boolean autocalculateConsensus = true;
128 public int ConsPercGaps = 25; // JBPNote : This should be a scalable property!
130 private java.beans.PropertyChangeSupport changeSupport = new java.beans.PropertyChangeSupport(
133 boolean ignoreGapsInConsensusCalculation = false;
135 public jalview.bin.JalviewLite applet;
137 Hashtable sequenceColours;
141 Stack historyList = new Stack();
143 Stack redoList = new Stack();
145 String sequenceSetID;
147 Hashtable hiddenRepSequences;
149 public void finalize() {
156 public AlignViewport(AlignmentI al, JalviewLite applet)
158 this.applet = applet;
161 this.endRes = al.getWidth() - 1;
163 this.endSeq = al.getHeight() - 1;
166 // get the width and height scaling factors if they were specified
167 String param = applet.getParameter("widthScale");
172 widthScale = new Float(param).floatValue();
173 } catch (Exception e)
176 if (widthScale <= 1.0)
179 .println("Invalid alignment character width scaling factor ("
180 + widthScale + "). Ignoring.");
186 .println("Alignment character width scaling factor is now "
190 param = applet.getParameter("heightScale");
195 heightScale = new Float(param).floatValue();
196 } catch (Exception e)
199 if (heightScale <= 1.0)
202 .println("Invalid alignment character height scaling factor ("
203 + heightScale + "). Ignoring.");
209 .println("Alignment character height scaling factor is now "
216 MAC = new jalview.util.Platform().isAMac();
220 String param = applet.getParameter("showFullId");
223 showJVSuffix = Boolean.valueOf(param).booleanValue();
226 param = applet.getParameter("showAnnotation");
229 showAnnotation = Boolean.valueOf(param).booleanValue();
232 param = applet.getParameter("showConservation");
235 showConservation = Boolean.valueOf(param).booleanValue();
238 param = applet.getParameter("showQuality");
241 showQuality = Boolean.valueOf(param).booleanValue();
244 param = applet.getParameter("showConsensus");
247 showConsensus = Boolean.valueOf(param).booleanValue();
250 param = applet.getParameter("showUnconserved");
253 this.showUnconserved = Boolean.valueOf(param).booleanValue();
256 param = applet.getParameter("upperCase");
259 if (param.equalsIgnoreCase("bold"))
261 upperCasebold = true;
264 param = applet.getParameter("sortByTree");
267 sortByTree = Boolean.valueOf(param).booleanValue();
269 param = applet.getParameter("automaticScrolling");
271 followHighlight = Boolean.valueOf(param).booleanValue();
272 followSelection = followHighlight;
274 if ((param=applet.getParameter("showSequenceLogo"))!=null) {
275 showSequenceLogo=Boolean.valueOf(param).booleanValue();
277 if ((param=applet.getParameter("showGroupConsensus"))!=null) {
278 showGroupConsensus=Boolean.valueOf(param).booleanValue();
280 if ((param=applet.getParameter("showGroupConservation"))!=null) {
281 showGroupConservation=Boolean.valueOf(param).booleanValue();
283 if ((param=applet.getParameter("showConsensusHistogram"))!=null) {
284 showConsensusHistogram=Boolean.valueOf(param).booleanValue();
291 String colour = applet.getParameter("defaultColour");
295 colour = applet.getParameter("userDefinedColour");
298 colour = "User Defined";
304 globalColourScheme = ColourSchemeProperty.getColour(alignment,
306 if (globalColourScheme != null)
308 globalColourScheme.setConsensus(hconsensus);
312 if (applet.getParameter("userDefinedColour") != null)
314 ((UserColourScheme) globalColourScheme).parseAppletParameter(applet
315 .getParameter("userDefinedColour"));
318 if (hconsensus == null)
320 if (!alignment.isNucleotide())
322 conservation = new AlignmentAnnotation("Conservation",
323 "Conservation of total alignment less than " + ConsPercGaps
324 + "% gaps", new Annotation[1], 0f, 11f,
325 AlignmentAnnotation.BAR_GRAPH);
326 conservation.hasText = true;
327 conservation.autoCalculated = true;
329 if (showConservation)
331 alignment.addAnnotation(conservation);
336 quality = new AlignmentAnnotation("Quality",
337 "Alignment Quality based on Blosum62 scores",
338 new Annotation[1], 0f, 11f, AlignmentAnnotation.BAR_GRAPH);
339 quality.hasText = true;
340 quality.autoCalculated = true;
342 alignment.addAnnotation(quality);
346 consensus = new AlignmentAnnotation("Consensus", "PID",
347 new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH);
348 consensus.hasText = true;
349 consensus.autoCalculated = true;
353 alignment.addAnnotation(consensus);
359 public void showSequenceFeatures(boolean b)
361 showSequenceFeatures = b;
364 public boolean getShowSequenceFeatures()
366 return showSequenceFeatures;
369 class ConservationThread extends Thread
373 public ConservationThread(AlignmentPanel ap)
382 updatingConservation = true;
384 while (UPDATING_CONSERVATION)
390 ap.paintAlignment(false);
393 } catch (Exception ex)
395 ex.printStackTrace();
399 UPDATING_CONSERVATION = true;
401 int alWidth = (alignment==null) ? -1 : alignment.getWidth();
404 updatingConservation = false;
405 UPDATING_CONSERVATION = false;
409 Conservation cons = new jalview.analysis.Conservation("All",
410 jalview.schemes.ResidueProperties.propHash, 3,
411 alignment.getSequences(), 0, alWidth - 1);
414 cons.verdict(false, ConsPercGaps);
421 char[] sequence = cons.getConsSequence().getSequence();
433 maxB = 0f - minB; // scalable range for colouring both Conservation and
443 conservation.annotations = new Annotation[alWidth];
447 quality.graphMax = cons.qualityRange[1].floatValue();
448 quality.annotations = new Annotation[alWidth];
449 qmin = cons.qualityRange[0].floatValue();
450 qmax = cons.qualityRange[1].floatValue();
453 for (int i = 0; i < alWidth; i++)
459 if (Character.isDigit(c))
461 value = (int) (c - '0');
471 // TODO - refactor to use a graduatedColorScheme to calculate the
473 float vprop = value - min;
475 conservation.annotations[i] = new Annotation(String.valueOf(c),
476 String.valueOf(value), ' ', value, new Color(minR
477 + (maxR * vprop), minG + (maxG * vprop), minB
483 value = ((Double) cons.quality.elementAt(i)).floatValue();
484 vprop = value - qmin;
486 quality.annotations[i] = new Annotation(" ",
487 String.valueOf(value), ' ', value, new Color(minR
488 + (maxR * vprop), minG + (maxG * vprop), minB
492 } catch (OutOfMemoryError error)
494 System.out.println("Out of memory calculating conservation!!");
500 UPDATING_CONSERVATION = false;
501 updatingConservation = false;
505 ap.paintAlignment(true);
511 ConservationThread conservationThread;
513 ConsensusThread consensusThread;
515 boolean consUpdateNeeded = false;
517 static boolean UPDATING_CONSENSUS = false;
519 static boolean UPDATING_CONSERVATION = false;
521 boolean updatingConsensus = false;
523 boolean updatingConservation = false;
528 public void updateConservation(final AlignmentPanel ap)
530 if (alignment.isNucleotide() || conservation == null)
535 conservationThread = new ConservationThread(ap);
536 conservationThread.start();
542 public void updateConsensus(final AlignmentPanel ap)
544 consensusThread = new ConsensusThread(ap);
545 consensusThread.start();
548 class ConsensusThread extends Thread
552 public ConsensusThread(AlignmentPanel ap)
559 updatingConsensus = true;
560 while (UPDATING_CONSENSUS)
566 ap.paintAlignment(false);
570 } catch (Exception ex)
572 ex.printStackTrace();
576 UPDATING_CONSENSUS = true;
580 int aWidth = alignment==null ? -1 : alignment.getWidth();
583 UPDATING_CONSENSUS = false;
584 updatingConsensus = false;
588 consensus.annotations = null;
589 consensus.annotations = new Annotation[aWidth];
591 hconsensus = new Hashtable[aWidth];
592 AAFrequency.calculate(alignment.getSequencesArray(), 0,
593 alignment.getWidth(), hconsensus, true); // always calculate the
595 updateAnnotation(true);
596 //AAFrequency.completeConsensus(consensus, hconsensus, 0, aWidth,
597 // ignoreGapsInConsensusCalculation,
600 if (globalColourScheme != null)
602 globalColourScheme.setConsensus(hconsensus);
605 } catch (OutOfMemoryError error)
607 alignment.deleteAnnotation(consensus);
611 System.out.println("Out of memory calculating consensus!!");
614 UPDATING_CONSENSUS = false;
615 updatingConsensus = false;
619 ap.paintAlignment(true);
624 * update the consensus annotation from the sequence profile data using
625 * current visualization settings.
627 public void updateAnnotation()
629 updateAnnotation(false);
632 protected void updateAnnotation(boolean immediate)
634 // TODO: make calls thread-safe, so if another thread calls this method,
635 // it will either return or wait until one calculation is finished.
637 || (!updatingConsensus && consensus != null && hconsensus != null))
639 AAFrequency.completeConsensus(consensus, hconsensus, 0,
640 hconsensus.length, ignoreGapsInConsensusCalculation,
647 * get the consensus sequence as displayed under the PID consensus annotation
650 * @return consensus sequence as a new sequence object
652 public SequenceI getConsensusSeq()
654 if (consensus == null)
656 updateConsensus(null);
658 if (consensus == null)
662 StringBuffer seqs = new StringBuffer();
663 for (int i = 0; i < consensus.annotations.length; i++)
665 if (consensus.annotations[i] != null)
667 if (consensus.annotations[i].description.charAt(0) == '[')
669 seqs.append(consensus.annotations[i].description.charAt(1));
673 seqs.append(consensus.annotations[i].displayCharacter);
677 SequenceI sq = new Sequence("Consensus", seqs.toString());
678 sq.setDescription("Percentage Identity Consensus "
679 + ((ignoreGapsInConsensusCalculation) ? " without gaps" : ""));
683 public SequenceGroup getSelectionGroup()
685 return selectionGroup;
688 public void setSelectionGroup(SequenceGroup sg)
693 public boolean getConservationSelected()
695 return conservationColourSelected;
698 public void setConservationSelected(boolean b)
700 conservationColourSelected = b;
703 public boolean getAbovePIDThreshold()
705 return abovePIDThreshold;
708 public void setAbovePIDThreshold(boolean b)
710 abovePIDThreshold = b;
713 public int getStartRes()
718 public int getEndRes()
723 public int getStartSeq()
728 public void setGlobalColourScheme(ColourSchemeI cs)
730 globalColourScheme = cs;
733 public ColourSchemeI getGlobalColourScheme()
735 return globalColourScheme;
738 public void setStartRes(int res)
743 public void setStartSeq(int seq)
748 public void setEndRes(int res)
750 if (res > alignment.getWidth() - 1)
752 // log.System.out.println(" Corrected res from " + res + " to maximum " +
753 // (alignment.getWidth()-1));
754 res = alignment.getWidth() - 1;
763 public void setEndSeq(int seq)
765 if (seq > alignment.getHeight())
767 seq = alignment.getHeight();
776 public int getEndSeq()
781 java.awt.Frame nullFrame;
783 protected FeatureSettings featureSettings = null;
785 private float heightScale = 1, widthScale = 1;
787 public void setFont(Font f)
790 if (nullFrame == null)
792 nullFrame = new java.awt.Frame();
793 nullFrame.addNotify();
796 java.awt.FontMetrics fm = nullFrame.getGraphics().getFontMetrics(font);
797 setCharHeight((int) (heightScale * fm.getHeight()));
798 charWidth = (int) (widthScale * fm.charWidth('M'));
802 Font f2 = new Font(f.getName(), Font.BOLD, f.getSize());
803 fm = nullFrame.getGraphics().getFontMetrics(f2);
804 charWidth = (int) (widthScale * (fm.stringWidth("MMMMMMMMMMM") / 10));
808 public Font getFont()
813 public int getCharWidth()
818 public void setCharHeight(int h)
823 public int getCharHeight()
828 public void setWrappedWidth(int w)
830 this.wrappedWidth = w;
833 public int getwrappedWidth()
838 public AlignmentI getAlignment()
843 public void setAlignment(AlignmentI align)
845 this.alignment = align;
848 public void setWrapAlignment(boolean state)
850 wrapAlignment = state;
853 public void setShowText(boolean state)
858 public void setRenderGaps(boolean state)
863 public boolean getColourText()
865 return showColourText;
868 public void setColourText(boolean state)
870 showColourText = state;
873 public void setShowBoxes(boolean state)
878 public boolean getWrapAlignment()
880 return wrapAlignment;
883 public boolean getShowText()
888 public boolean getShowBoxes()
893 public char getGapCharacter()
895 return getAlignment().getGapCharacter();
898 public void setGapCharacter(char gap)
900 if (getAlignment() != null)
902 getAlignment().setGapCharacter(gap);
906 public void setThreshold(int thresh)
911 public int getThreshold()
916 public void setIncrement(int inc)
921 public int getIncrement()
926 public void setHiddenColumns(ColumnSelection colsel)
928 this.colSel = colsel;
929 if (colSel.getHiddenColumns() != null)
931 hasHiddenColumns = true;
935 public ColumnSelection getColumnSelection()
940 public void resetSeqLimits(int height)
942 setEndSeq(height / getCharHeight());
945 public void setCurrentTree(NJTree tree)
950 public NJTree getCurrentTree()
955 public void setColourAppliesToAllGroups(boolean b)
957 colourAppliesToAllGroups = b;
960 public boolean getColourAppliesToAllGroups()
962 return colourAppliesToAllGroups;
965 public boolean getShowJVSuffix()
970 public void setShowJVSuffix(boolean b)
975 public boolean getShowAnnotation()
977 return showAnnotation;
980 public void setShowAnnotation(boolean b)
985 public boolean getScaleAboveWrapped()
987 return scaleAboveWrapped;
990 public boolean getScaleLeftWrapped()
992 return scaleLeftWrapped;
995 public boolean getScaleRightWrapped()
997 return scaleRightWrapped;
1000 public void setScaleAboveWrapped(boolean b)
1002 scaleAboveWrapped = b;
1005 public void setScaleLeftWrapped(boolean b)
1007 scaleLeftWrapped = b;
1010 public void setScaleRightWrapped(boolean b)
1012 scaleRightWrapped = b;
1015 public void setIgnoreGapsConsensus(boolean b)
1017 ignoreGapsInConsensusCalculation = b;
1018 updateConsensus(null);
1019 if (globalColourScheme != null)
1021 globalColourScheme.setThreshold(globalColourScheme.getThreshold(),
1022 ignoreGapsInConsensusCalculation);
1028 * Property change listener for changes in alignment
1033 public void addPropertyChangeListener(
1034 java.beans.PropertyChangeListener listener)
1036 changeSupport.addPropertyChangeListener(listener);
1045 public void removePropertyChangeListener(
1046 java.beans.PropertyChangeListener listener)
1048 changeSupport.removePropertyChangeListener(listener);
1052 * Property change listener for changes in alignment
1061 public void firePropertyChange(String prop, Object oldvalue,
1064 changeSupport.firePropertyChange(prop, oldvalue, newvalue);
1067 public boolean getIgnoreGapsConsensus()
1069 return ignoreGapsInConsensusCalculation;
1072 public void hideSelectedColumns()
1074 if (colSel.size() < 1)
1079 colSel.hideSelectedColumns();
1080 setSelectionGroup(null);
1082 hasHiddenColumns = true;
1085 public void invertColumnSelection()
1087 for (int i = 0; i < alignment.getWidth(); i++)
1089 if (colSel.contains(i))
1091 colSel.removeElement(i);
1095 if (!hasHiddenColumns || colSel.isVisible(i))
1097 colSel.addElement(i);
1103 public void hideColumns(int start, int end)
1107 colSel.hideColumns(start);
1111 colSel.hideColumns(start, end);
1114 hasHiddenColumns = true;
1117 public void hideRepSequences(SequenceI repSequence, SequenceGroup sg)
1119 int sSize = sg.getSize();
1125 if (hiddenRepSequences == null)
1127 hiddenRepSequences = new Hashtable();
1130 hiddenRepSequences.put(repSequence, sg);
1132 // Hide all sequences except the repSequence
1133 SequenceI[] seqs = new SequenceI[sSize - 1];
1135 for (int i = 0; i < sSize; i++)
1137 if (sg.getSequenceAt(i) != repSequence)
1139 if (index == sSize - 1)
1144 seqs[index++] = sg.getSequenceAt(i);
1152 public void hideAllSelectedSeqs()
1154 if (selectionGroup == null || selectionGroup.getSize() < 1)
1159 SequenceI[] seqs = selectionGroup.getSequencesInOrder(alignment);
1163 setSelectionGroup(null);
1166 public void hideSequence(SequenceI[] seq)
1170 for (int i = 0; i < seq.length; i++)
1172 alignment.getHiddenSequences().hideSequence(seq[i]);
1175 hasHiddenRows = true;
1176 firePropertyChange("alignment", null, alignment.getSequences());
1179 public void showSequence(int index)
1181 Vector tmp = alignment.getHiddenSequences().showSequence(index,
1182 hiddenRepSequences);
1185 if (selectionGroup == null)
1187 selectionGroup = new SequenceGroup();
1188 selectionGroup.setEndRes(alignment.getWidth() - 1);
1191 for (int t = 0; t < tmp.size(); t++)
1193 selectionGroup.addSequence((SequenceI) tmp.elementAt(t), false);
1195 firePropertyChange("alignment", null, alignment.getSequences());
1199 if (alignment.getHiddenSequences().getSize() < 1)
1201 hasHiddenRows = false;
1204 public void showColumn(int col)
1206 colSel.revealHiddenColumns(col);
1207 if (colSel.getHiddenColumns() == null)
1209 hasHiddenColumns = false;
1213 public void showAllHiddenColumns()
1215 colSel.revealAllHiddenColumns();
1216 hasHiddenColumns = false;
1219 public void showAllHiddenSeqs()
1221 if (alignment.getHiddenSequences().getSize() > 0)
1223 if (selectionGroup == null)
1225 selectionGroup = new SequenceGroup();
1226 selectionGroup.setEndRes(alignment.getWidth() - 1);
1228 Vector tmp = alignment.getHiddenSequences().showAll(
1229 hiddenRepSequences);
1230 for (int t = 0; t < tmp.size(); t++)
1232 selectionGroup.addSequence((SequenceI) tmp.elementAt(t), false);
1234 firePropertyChange("alignment", null, alignment.getSequences());
1235 hasHiddenRows = false;
1236 hiddenRepSequences = null;
1241 public int adjustForHiddenSeqs(int alignmentIndex)
1243 return alignment.getHiddenSequences().adjustForHiddenSeqs(
1248 * This method returns the a new SequenceI [] with the selection sequence and
1249 * start and end points adjusted
1253 public SequenceI[] getSelectionAsNewSequence()
1255 SequenceI[] sequences;
1257 if (selectionGroup == null)
1259 sequences = alignment.getSequencesArray();
1263 sequences = selectionGroup.getSelectionAsNewSequences(alignment);
1270 * get the currently selected sequence objects or all the sequences in the
1273 * @return array of references to sequence objects
1275 public SequenceI[] getSequenceSelection()
1277 SequenceI[] sequences = null;
1278 if (selectionGroup != null)
1280 sequences = selectionGroup.getSequencesInOrder(alignment);
1282 if (sequences == null)
1284 sequences = alignment.getSequencesArray();
1290 * This method returns the visible alignment as text, as seen on the GUI, ie
1291 * if columns are hidden they will not be returned in the result. Use this for
1292 * calculating trees, PCA, redundancy etc on views which contain hidden
1297 public jalview.datamodel.CigarArray getViewAsCigars(
1298 boolean selectedRegionOnly)
1300 return new jalview.datamodel.CigarArray(alignment, (hasHiddenColumns ? colSel : null), (selectedRegionOnly ? selectionGroup : null));
1304 * return a compact representation of the current alignment selection to pass
1305 * to an analysis function
1307 * @param selectedOnly
1308 * boolean true to just return the selected view
1309 * @return AlignmentView
1311 jalview.datamodel.AlignmentView getAlignmentView(boolean selectedOnly)
1313 return getAlignmentView(selectedOnly, false);
1317 * return a compact representation of the current alignment selection to pass
1318 * to an analysis function
1320 * @param selectedOnly
1321 * boolean true to just return the selected view
1323 * boolean true to annotate the alignment view with groups on the alignment (and intersecting with selected region if selectedOnly is true)
1324 * @return AlignmentView
1326 public jalview.datamodel.AlignmentView getAlignmentView(boolean selectedOnly, boolean markGroups)
1328 return new AlignmentView(alignment, colSel, selectionGroup, hasHiddenColumns, selectedOnly, markGroups);
1331 * This method returns the visible alignment as text, as seen on the GUI, ie
1332 * if columns are hidden they will not be returned in the result. Use this for
1333 * calculating trees, PCA, redundancy etc on views which contain hidden
1338 public String[] getViewAsString(boolean selectedRegionOnly)
1340 String[] selection = null;
1341 SequenceI[] seqs = null;
1343 int start = 0, end = 0;
1344 if (selectedRegionOnly && selectionGroup != null)
1346 iSize = selectionGroup.getSize();
1347 seqs = selectionGroup.getSequencesInOrder(alignment);
1348 start = selectionGroup.getStartRes();
1349 end = selectionGroup.getEndRes() + 1;
1353 iSize = alignment.getHeight();
1354 seqs = alignment.getSequencesArray();
1355 end = alignment.getWidth();
1358 selection = new String[iSize];
1360 for (i = 0; i < iSize; i++)
1362 if (hasHiddenColumns)
1364 StringBuffer visibleSeq = new StringBuffer();
1365 Vector regions = colSel.getHiddenColumns();
1367 int blockStart = start, blockEnd = end;
1369 int hideStart, hideEnd;
1371 for (int j = 0; j < regions.size(); j++)
1373 region = (int[]) regions.elementAt(j);
1374 hideStart = region[0];
1375 hideEnd = region[1];
1377 if (hideStart < start)
1382 blockStart = Math.min(blockStart, hideEnd + 1);
1383 blockEnd = Math.min(blockEnd, hideStart);
1385 if (blockStart > blockEnd)
1390 visibleSeq.append(seqs[i].getSequence(blockStart, blockEnd));
1392 blockStart = hideEnd + 1;
1396 if (end > blockStart)
1398 visibleSeq.append(seqs[i].getSequence(blockStart, end));
1401 selection[i] = visibleSeq.toString();
1405 selection[i] = seqs[i].getSequenceAsString(start, end);
1412 public boolean getShowHiddenMarkers()
1414 return showHiddenMarkers;
1417 public void setShowHiddenMarkers(boolean show)
1419 showHiddenMarkers = show;
1422 public Color getSequenceColour(SequenceI seq)
1424 if (sequenceColours == null || !sequenceColours.containsKey(seq))
1430 return (Color) sequenceColours.get(seq);
1434 public void setSequenceColour(SequenceI seq, Color col)
1436 if (sequenceColours == null)
1438 sequenceColours = new Hashtable();
1443 sequenceColours.remove(seq);
1447 sequenceColours.put(seq, col);
1451 public String getSequenceSetId()
1453 if (sequenceSetID == null)
1455 sequenceSetID = alignment.hashCode() + "";
1458 return sequenceSetID;
1461 * unique viewId for synchronizing state (e.g. with stored Jalview Project)
1464 private String viewId = null;
1466 public String getViewId()
1470 viewId = this.getSequenceSetId() + "." + this.hashCode() + "";
1475 public void alignmentChanged(AlignmentPanel ap)
1477 alignment.padGaps();
1479 if (hconsensus != null && autocalculateConsensus)
1481 updateConsensus(ap);
1482 updateConservation(ap);
1485 // Reset endRes of groups if beyond alignment width
1486 int alWidth = alignment.getWidth();
1487 Vector groups = alignment.getGroups();
1490 for (int i = 0; i < groups.size(); i++)
1492 SequenceGroup sg = (SequenceGroup) groups.elementAt(i);
1493 if (sg.getEndRes() > alWidth)
1495 sg.setEndRes(alWidth - 1);
1500 if (selectionGroup != null && selectionGroup.getEndRes() > alWidth)
1502 selectionGroup.setEndRes(alWidth - 1);
1505 resetAllColourSchemes();
1507 // AW alignment.adjustSequenceAnnotations();
1510 void resetAllColourSchemes()
1512 ColourSchemeI cs = globalColourScheme;
1515 if (cs instanceof ClustalxColourScheme)
1517 ((ClustalxColourScheme) cs).resetClustalX(alignment.getSequences(),
1518 alignment.getWidth());
1521 cs.setConsensus(hconsensus);
1522 if (cs.conservationApplied())
1524 Alignment al = (Alignment) alignment;
1525 Conservation c = new Conservation("All",
1526 ResidueProperties.propHash, 3, al.getSequences(), 0,
1529 c.verdict(false, ConsPercGaps);
1531 cs.setConservation(c);
1535 int s, sSize = alignment.getGroups().size();
1536 for (s = 0; s < sSize; s++)
1538 SequenceGroup sg = (SequenceGroup) alignment.getGroups().elementAt(s);
1539 if (sg.cs != null && sg.cs instanceof ClustalxColourScheme)
1541 ((ClustalxColourScheme) sg.cs).resetClustalX(
1542 sg.getSequences(hiddenRepSequences), sg.getWidth());
1544 sg.recalcConservation();
1548 boolean centreColumnLabels;
1550 public boolean getCentreColumnLabels()
1552 return centreColumnLabels;
1555 public void updateSequenceIdColours()
1557 Vector groups = alignment.getGroups();
1558 for (int ig = 0, igSize = groups.size(); ig < igSize; ig++)
1560 SequenceGroup sg = (SequenceGroup) groups.elementAt(ig);
1561 if (sg.idColour != null)
1563 Vector sqs = sg.getSequences(hiddenRepSequences);
1564 for (int s = 0, sSize = sqs.size(); s < sSize; s++)
1566 this.setSequenceColour((SequenceI) sqs.elementAt(s), sg.idColour);
1572 public boolean followHighlight = false;
1574 public boolean getFollowHighlight()
1576 return followHighlight;
1579 public boolean followSelection = true;
1582 * @return true if view selection should always follow the selections
1583 * broadcast by other selection sources
1585 public boolean getFollowSelection()
1587 return followSelection;
1590 private long sgrouphash = -1, colselhash = -1;
1593 * checks current SelectionGroup against record of last hash value, and
1596 * @return true if SelectionGroup changed since last call
1598 boolean isSelectionGroupChanged()
1600 int hc = (selectionGroup == null) ? -1 : selectionGroup.hashCode();
1601 if (hc != sgrouphash)
1610 * checks current colsel against record of last hash value, and updates
1613 * @return true if colsel changed since last call
1615 boolean isColSelChanged()
1617 int hc = (colSel == null) ? -1 : colSel.hashCode();
1618 if (hc != colselhash)
1625 public void sendSelection()
1627 jalview.structure.StructureSelectionManager
1628 .getStructureSelectionManager(applet).sendSelection(
1629 new SequenceGroup(getSelectionGroup()),
1630 new ColumnSelection(getColumnSelection()), this);
1637 * show non-conserved residues only
1639 public boolean showUnconserved = false;
1642 * when set, alignment should be reordered according to a newly opened tree
1644 public boolean sortByTree = false;
1647 * @return the showUnconserved
1649 public boolean getShowunconserved()
1651 return showUnconserved;
1655 * @param showNonconserved
1656 * the showUnconserved to set
1658 public void setShowunconserved(boolean displayNonconserved)
1660 this.showUnconserved = displayNonconserved;
1664 * should conservation rows be shown for groups
1666 boolean showGroupConservation = false;
1669 * should consensus rows be shown for groups
1671 boolean showGroupConsensus = false;
1674 * should consensus profile be rendered by default
1676 public boolean showSequenceLogo = false;
1679 * should consensus histograms be rendered by default
1681 public boolean showConsensusHistogram = true;
1684 * @return the showConsensusProfile
1686 public boolean isShowSequenceLogo()
1688 return showSequenceLogo;
1692 * @param showSequenceLogo
1695 public void setShowSequenceLogo(boolean showSequenceLogo)
1697 if (showSequenceLogo != this.showSequenceLogo)
1699 // TODO: decouple settings setting from calculation when refactoring
1700 // annotation update method from alignframe to viewport
1701 this.showSequenceLogo = showSequenceLogo;
1702 if (consensusThread != null)
1704 consensusThread.updateAnnotation();
1707 this.showSequenceLogo = showSequenceLogo;
1711 * @param showConsensusHistogram
1712 * the showConsensusHistogram to set
1714 public void setShowConsensusHistogram(boolean showConsensusHistogram)
1716 this.showConsensusHistogram = showConsensusHistogram;
1720 * @return the showGroupConservation
1722 public boolean isShowGroupConservation()
1724 return showGroupConservation;
1728 * @param showGroupConservation
1729 * the showGroupConservation to set
1731 public void setShowGroupConservation(boolean showGroupConservation)
1733 this.showGroupConservation = showGroupConservation;
1737 * @return the showGroupConsensus
1739 public boolean isShowGroupConsensus()
1741 return showGroupConsensus;
1745 * @param showGroupConsensus
1746 * the showGroupConsensus to set
1748 public void setShowGroupConsensus(boolean showGroupConsensus)
1750 this.showGroupConsensus = showGroupConsensus;
1755 * @return flag to indicate if the consensus histogram should be rendered by
1758 public boolean isShowConsensusHistogram()
1760 return this.showConsensusHistogram;
1764 * synthesize a column selection if none exists so it covers the given
1765 * selection group. if wholewidth is false, no column selection is made if the
1766 * selection group covers the whole alignment width.
1771 public void expandColSelection(SequenceGroup sg, boolean wholewidth)
1775 && (sgs = sg.getStartRes()) >= 0
1776 && sg.getStartRes() <= (sge = sg.getEndRes())
1777 && (colSel == null || colSel.getSelected() == null || colSel
1778 .getSelected().size() == 0))
1780 if (!wholewidth && alignment.getWidth() == (1 + sge - sgs))
1787 colSel = new ColumnSelection();
1789 for (int cspos = sg.getStartRes(); cspos <= sg.getEndRes(); cspos++)
1791 colSel.addElement(cspos);