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.VamsasSource;
31 public class AlignViewport implements SelectionSource, VamsasSource
41 boolean cursorMode = false;
43 boolean showJVSuffix = true;
45 boolean showText = true;
47 boolean showColourText = false;
49 boolean showBoxes = true;
51 boolean wrapAlignment = false;
53 boolean renderGaps = true;
55 boolean showSequenceFeatures = false;
57 boolean showAnnotation = true;
59 boolean showConservation = true;
61 boolean showQuality = true;
63 boolean showConsensus = true;
65 boolean upperCasebold = false;
67 boolean colourAppliesToAllGroups = true;
69 ColourSchemeI globalColourScheme = null;
71 boolean conservationColourSelected = false;
73 boolean abovePIDThreshold = false;
75 SequenceGroup selectionGroup;
83 Font font = new Font("SansSerif", Font.PLAIN, 10);
85 boolean validCharWidth = true;
89 ColumnSelection colSel = new ColumnSelection();
95 NJTree currentTree = null;
97 boolean scaleAboveWrapped = true;
99 boolean scaleLeftWrapped = true;
101 boolean scaleRightWrapped = true;
103 // The following vector holds the features which are
104 // currently visible, in the correct order or rendering
105 public Hashtable featuresDisplayed;
107 boolean hasHiddenColumns = false;
109 boolean hasHiddenRows = false;
111 boolean showHiddenMarkers = true;
113 public Hashtable[] hconsensus;
115 AlignmentAnnotation consensus;
117 AlignmentAnnotation conservation;
119 AlignmentAnnotation quality;
121 AlignmentAnnotation[] groupConsensus;
123 AlignmentAnnotation[] groupConservation;
125 boolean autocalculateConsensus = true;
127 public int ConsPercGaps = 25; // JBPNote : This should be a scalable property!
129 private java.beans.PropertyChangeSupport changeSupport = new java.beans.PropertyChangeSupport(
132 boolean ignoreGapsInConsensusCalculation = false;
134 public jalview.bin.JalviewLite applet;
136 Hashtable sequenceColours;
140 Stack historyList = new Stack();
142 Stack redoList = new Stack();
144 String sequenceSetID;
146 Hashtable hiddenRepSequences;
148 public AlignViewport(AlignmentI al, JalviewLite applet)
150 this.applet = applet;
153 this.endRes = al.getWidth() - 1;
155 this.endSeq = al.getHeight() - 1;
158 // get the width and height scaling factors if they were specified
159 String param = applet.getParameter("widthScale");
164 widthScale = new Float(param).floatValue();
165 } catch (Exception e)
168 if (widthScale <= 1.0)
171 .println("Invalid alignment character width scaling factor ("
172 + widthScale + "). Ignoring.");
178 .println("Alignment character width scaling factor is now "
182 param = applet.getParameter("heightScale");
187 heightScale = new Float(param).floatValue();
188 } catch (Exception e)
191 if (heightScale <= 1.0)
194 .println("Invalid alignment character height scaling factor ("
195 + heightScale + "). Ignoring.");
201 .println("Alignment character height scaling factor is now "
208 MAC = new jalview.util.Platform().isAMac();
212 String param = applet.getParameter("showFullId");
215 showJVSuffix = Boolean.valueOf(param).booleanValue();
218 param = applet.getParameter("showAnnotation");
221 showAnnotation = Boolean.valueOf(param).booleanValue();
224 param = applet.getParameter("showConservation");
227 showConservation = Boolean.valueOf(param).booleanValue();
230 param = applet.getParameter("showQuality");
233 showQuality = Boolean.valueOf(param).booleanValue();
236 param = applet.getParameter("showConsensus");
239 showConsensus = Boolean.valueOf(param).booleanValue();
242 param = applet.getParameter("showUnconserved");
245 this.showUnconserved = Boolean.valueOf(param).booleanValue();
248 param = applet.getParameter("upperCase");
251 if (param.equalsIgnoreCase("bold"))
253 upperCasebold = true;
256 param = applet.getParameter("sortByTree");
259 sortByTree = Boolean.valueOf(param).booleanValue();
261 param = applet.getParameter("automaticScrolling");
263 followHighlight = Boolean.valueOf(param).booleanValue();
264 followSelection = followHighlight;
266 if ((param=applet.getParameter("showSequenceLogo"))!=null) {
267 showSequenceLogo=Boolean.valueOf(param).booleanValue();
269 if ((param=applet.getParameter("showGroupConsensus"))!=null) {
270 showGroupConsensus=Boolean.valueOf(param).booleanValue();
272 if ((param=applet.getParameter("showGroupConservation"))!=null) {
273 showGroupConservation=Boolean.valueOf(param).booleanValue();
275 if ((param=applet.getParameter("showConsensusHistogram"))!=null) {
276 showConsensusHistogram=Boolean.valueOf(param).booleanValue();
283 String colour = applet.getParameter("defaultColour");
287 colour = applet.getParameter("userDefinedColour");
290 colour = "User Defined";
296 globalColourScheme = ColourSchemeProperty.getColour(alignment,
298 if (globalColourScheme != null)
300 globalColourScheme.setConsensus(hconsensus);
304 if (applet.getParameter("userDefinedColour") != null)
306 ((UserColourScheme) globalColourScheme).parseAppletParameter(applet
307 .getParameter("userDefinedColour"));
310 if (hconsensus == null)
312 if (!alignment.isNucleotide())
314 conservation = new AlignmentAnnotation("Conservation",
315 "Conservation of total alignment less than " + ConsPercGaps
316 + "% gaps", new Annotation[1], 0f, 11f,
317 AlignmentAnnotation.BAR_GRAPH);
318 conservation.hasText = true;
319 conservation.autoCalculated = true;
321 if (showConservation)
323 alignment.addAnnotation(conservation);
328 quality = new AlignmentAnnotation("Quality",
329 "Alignment Quality based on Blosum62 scores",
330 new Annotation[1], 0f, 11f, AlignmentAnnotation.BAR_GRAPH);
331 quality.hasText = true;
332 quality.autoCalculated = true;
334 alignment.addAnnotation(quality);
338 consensus = new AlignmentAnnotation("Consensus", "PID",
339 new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH);
340 consensus.hasText = true;
341 consensus.autoCalculated = true;
345 alignment.addAnnotation(consensus);
351 public void showSequenceFeatures(boolean b)
353 showSequenceFeatures = b;
356 public boolean getShowSequenceFeatures()
358 return showSequenceFeatures;
361 class ConservationThread extends Thread
365 public ConservationThread(AlignmentPanel ap)
374 updatingConservation = true;
376 while (UPDATING_CONSERVATION)
382 ap.paintAlignment(false);
385 } catch (Exception ex)
387 ex.printStackTrace();
391 UPDATING_CONSERVATION = true;
393 int alWidth = (alignment==null) ? -1 : alignment.getWidth();
396 updatingConservation = false;
397 UPDATING_CONSERVATION = false;
401 Conservation cons = new jalview.analysis.Conservation("All",
402 jalview.schemes.ResidueProperties.propHash, 3,
403 alignment.getSequences(), 0, alWidth - 1);
406 cons.verdict(false, ConsPercGaps);
413 char[] sequence = cons.getConsSequence().getSequence();
425 maxB = 0f - minB; // scalable range for colouring both Conservation and
435 conservation.annotations = new Annotation[alWidth];
439 quality.graphMax = cons.qualityRange[1].floatValue();
440 quality.annotations = new Annotation[alWidth];
441 qmin = cons.qualityRange[0].floatValue();
442 qmax = cons.qualityRange[1].floatValue();
445 for (int i = 0; i < alWidth; i++)
451 if (Character.isDigit(c))
453 value = (int) (c - '0');
463 // TODO - refactor to use a graduatedColorScheme to calculate the
465 float vprop = value - min;
467 conservation.annotations[i] = new Annotation(String.valueOf(c),
468 String.valueOf(value), ' ', value, new Color(minR
469 + (maxR * vprop), minG + (maxG * vprop), minB
475 value = ((Double) cons.quality.elementAt(i)).floatValue();
476 vprop = value - qmin;
478 quality.annotations[i] = new Annotation(" ",
479 String.valueOf(value), ' ', value, new Color(minR
480 + (maxR * vprop), minG + (maxG * vprop), minB
484 } catch (OutOfMemoryError error)
486 System.out.println("Out of memory calculating conservation!!");
492 UPDATING_CONSERVATION = false;
493 updatingConservation = false;
497 ap.paintAlignment(true);
503 ConservationThread conservationThread;
505 ConsensusThread consensusThread;
507 boolean consUpdateNeeded = false;
509 static boolean UPDATING_CONSENSUS = false;
511 static boolean UPDATING_CONSERVATION = false;
513 boolean updatingConsensus = false;
515 boolean updatingConservation = false;
520 public void updateConservation(final AlignmentPanel ap)
522 if (alignment.isNucleotide() || conservation == null)
527 conservationThread = new ConservationThread(ap);
528 conservationThread.start();
534 public void updateConsensus(final AlignmentPanel ap)
536 consensusThread = new ConsensusThread(ap);
537 consensusThread.start();
540 class ConsensusThread extends Thread
544 public ConsensusThread(AlignmentPanel ap)
551 updatingConsensus = true;
552 while (UPDATING_CONSENSUS)
558 ap.paintAlignment(false);
562 } catch (Exception ex)
564 ex.printStackTrace();
568 UPDATING_CONSENSUS = true;
572 int aWidth = alignment==null ? -1 : alignment.getWidth();
575 UPDATING_CONSENSUS = false;
576 updatingConsensus = false;
580 consensus.annotations = null;
581 consensus.annotations = new Annotation[aWidth];
583 hconsensus = new Hashtable[aWidth];
584 AAFrequency.calculate(alignment.getSequencesArray(), 0,
585 alignment.getWidth(), hconsensus, true); // always calculate the
587 updateAnnotation(true);
588 //AAFrequency.completeConsensus(consensus, hconsensus, 0, aWidth,
589 // ignoreGapsInConsensusCalculation,
592 if (globalColourScheme != null)
594 globalColourScheme.setConsensus(hconsensus);
597 } catch (OutOfMemoryError error)
599 alignment.deleteAnnotation(consensus);
603 System.out.println("Out of memory calculating consensus!!");
606 UPDATING_CONSENSUS = false;
607 updatingConsensus = false;
611 ap.paintAlignment(true);
616 * update the consensus annotation from the sequence profile data using
617 * current visualization settings.
619 public void updateAnnotation()
621 updateAnnotation(false);
624 protected void updateAnnotation(boolean immediate)
626 // TODO: make calls thread-safe, so if another thread calls this method,
627 // it will either return or wait until one calculation is finished.
629 || (!updatingConsensus && consensus != null && hconsensus != null))
631 AAFrequency.completeConsensus(consensus, hconsensus, 0,
632 hconsensus.length, ignoreGapsInConsensusCalculation,
639 * get the consensus sequence as displayed under the PID consensus annotation
642 * @return consensus sequence as a new sequence object
644 public SequenceI getConsensusSeq()
646 if (consensus == null)
648 updateConsensus(null);
650 if (consensus == null)
654 StringBuffer seqs = new StringBuffer();
655 for (int i = 0; i < consensus.annotations.length; i++)
657 if (consensus.annotations[i] != null)
659 if (consensus.annotations[i].description.charAt(0) == '[')
661 seqs.append(consensus.annotations[i].description.charAt(1));
665 seqs.append(consensus.annotations[i].displayCharacter);
669 SequenceI sq = new Sequence("Consensus", seqs.toString());
670 sq.setDescription("Percentage Identity Consensus "
671 + ((ignoreGapsInConsensusCalculation) ? " without gaps" : ""));
675 public SequenceGroup getSelectionGroup()
677 return selectionGroup;
680 public void setSelectionGroup(SequenceGroup sg)
685 public boolean getConservationSelected()
687 return conservationColourSelected;
690 public void setConservationSelected(boolean b)
692 conservationColourSelected = b;
695 public boolean getAbovePIDThreshold()
697 return abovePIDThreshold;
700 public void setAbovePIDThreshold(boolean b)
702 abovePIDThreshold = b;
705 public int getStartRes()
710 public int getEndRes()
715 public int getStartSeq()
720 public void setGlobalColourScheme(ColourSchemeI cs)
722 globalColourScheme = cs;
725 public ColourSchemeI getGlobalColourScheme()
727 return globalColourScheme;
730 public void setStartRes(int res)
735 public void setStartSeq(int seq)
740 public void setEndRes(int res)
742 if (res > alignment.getWidth() - 1)
744 // log.System.out.println(" Corrected res from " + res + " to maximum " +
745 // (alignment.getWidth()-1));
746 res = alignment.getWidth() - 1;
755 public void setEndSeq(int seq)
757 if (seq > alignment.getHeight())
759 seq = alignment.getHeight();
768 public int getEndSeq()
773 java.awt.Frame nullFrame;
775 protected FeatureSettings featureSettings = null;
777 private float heightScale = 1, widthScale = 1;
779 public void setFont(Font f)
782 if (nullFrame == null)
784 nullFrame = new java.awt.Frame();
785 nullFrame.addNotify();
788 java.awt.FontMetrics fm = nullFrame.getGraphics().getFontMetrics(font);
789 setCharHeight((int) (heightScale * fm.getHeight()));
790 charWidth = (int) (widthScale * fm.charWidth('M'));
794 Font f2 = new Font(f.getName(), Font.BOLD, f.getSize());
795 fm = nullFrame.getGraphics().getFontMetrics(f2);
796 charWidth = (int) (widthScale * (fm.stringWidth("MMMMMMMMMMM") / 10));
800 public Font getFont()
805 public int getCharWidth()
810 public void setCharHeight(int h)
815 public int getCharHeight()
820 public void setWrappedWidth(int w)
822 this.wrappedWidth = w;
825 public int getwrappedWidth()
830 public AlignmentI getAlignment()
835 public void setAlignment(AlignmentI align)
837 this.alignment = align;
840 public void setWrapAlignment(boolean state)
842 wrapAlignment = state;
845 public void setShowText(boolean state)
850 public void setRenderGaps(boolean state)
855 public boolean getColourText()
857 return showColourText;
860 public void setColourText(boolean state)
862 showColourText = state;
865 public void setShowBoxes(boolean state)
870 public boolean getWrapAlignment()
872 return wrapAlignment;
875 public boolean getShowText()
880 public boolean getShowBoxes()
885 public char getGapCharacter()
887 return getAlignment().getGapCharacter();
890 public void setGapCharacter(char gap)
892 if (getAlignment() != null)
894 getAlignment().setGapCharacter(gap);
898 public void setThreshold(int thresh)
903 public int getThreshold()
908 public void setIncrement(int inc)
913 public int getIncrement()
918 public void setHiddenColumns(ColumnSelection colsel)
920 this.colSel = colsel;
921 if (colSel.getHiddenColumns() != null)
923 hasHiddenColumns = true;
927 public ColumnSelection getColumnSelection()
932 public void resetSeqLimits(int height)
934 setEndSeq(height / getCharHeight());
937 public void setCurrentTree(NJTree tree)
942 public NJTree getCurrentTree()
947 public void setColourAppliesToAllGroups(boolean b)
949 colourAppliesToAllGroups = b;
952 public boolean getColourAppliesToAllGroups()
954 return colourAppliesToAllGroups;
957 public boolean getShowJVSuffix()
962 public void setShowJVSuffix(boolean b)
967 public boolean getShowAnnotation()
969 return showAnnotation;
972 public void setShowAnnotation(boolean b)
977 public boolean getScaleAboveWrapped()
979 return scaleAboveWrapped;
982 public boolean getScaleLeftWrapped()
984 return scaleLeftWrapped;
987 public boolean getScaleRightWrapped()
989 return scaleRightWrapped;
992 public void setScaleAboveWrapped(boolean b)
994 scaleAboveWrapped = b;
997 public void setScaleLeftWrapped(boolean b)
999 scaleLeftWrapped = b;
1002 public void setScaleRightWrapped(boolean b)
1004 scaleRightWrapped = b;
1007 public void setIgnoreGapsConsensus(boolean b)
1009 ignoreGapsInConsensusCalculation = b;
1010 updateConsensus(null);
1011 if (globalColourScheme != null)
1013 globalColourScheme.setThreshold(globalColourScheme.getThreshold(),
1014 ignoreGapsInConsensusCalculation);
1020 * Property change listener for changes in alignment
1025 public void addPropertyChangeListener(
1026 java.beans.PropertyChangeListener listener)
1028 changeSupport.addPropertyChangeListener(listener);
1037 public void removePropertyChangeListener(
1038 java.beans.PropertyChangeListener listener)
1040 changeSupport.removePropertyChangeListener(listener);
1044 * Property change listener for changes in alignment
1053 public void firePropertyChange(String prop, Object oldvalue,
1056 changeSupport.firePropertyChange(prop, oldvalue, newvalue);
1059 public boolean getIgnoreGapsConsensus()
1061 return ignoreGapsInConsensusCalculation;
1064 public void hideSelectedColumns()
1066 if (colSel.size() < 1)
1071 colSel.hideSelectedColumns();
1072 setSelectionGroup(null);
1074 hasHiddenColumns = true;
1077 public void invertColumnSelection()
1079 for (int i = 0; i < alignment.getWidth(); i++)
1081 if (colSel.contains(i))
1083 colSel.removeElement(i);
1087 if (!hasHiddenColumns || colSel.isVisible(i))
1089 colSel.addElement(i);
1095 public void hideColumns(int start, int end)
1099 colSel.hideColumns(start);
1103 colSel.hideColumns(start, end);
1106 hasHiddenColumns = true;
1109 public void hideRepSequences(SequenceI repSequence, SequenceGroup sg)
1111 int sSize = sg.getSize();
1117 if (hiddenRepSequences == null)
1119 hiddenRepSequences = new Hashtable();
1122 hiddenRepSequences.put(repSequence, sg);
1124 // Hide all sequences except the repSequence
1125 SequenceI[] seqs = new SequenceI[sSize - 1];
1127 for (int i = 0; i < sSize; i++)
1129 if (sg.getSequenceAt(i) != repSequence)
1131 if (index == sSize - 1)
1136 seqs[index++] = sg.getSequenceAt(i);
1144 public void hideAllSelectedSeqs()
1146 if (selectionGroup == null || selectionGroup.getSize() < 1)
1151 SequenceI[] seqs = selectionGroup.getSequencesInOrder(alignment);
1155 setSelectionGroup(null);
1158 public void hideSequence(SequenceI[] seq)
1162 for (int i = 0; i < seq.length; i++)
1164 alignment.getHiddenSequences().hideSequence(seq[i]);
1167 hasHiddenRows = true;
1168 firePropertyChange("alignment", null, alignment.getSequences());
1171 public void showSequence(int index)
1173 Vector tmp = alignment.getHiddenSequences().showSequence(index,
1174 hiddenRepSequences);
1177 if (selectionGroup == null)
1179 selectionGroup = new SequenceGroup();
1180 selectionGroup.setEndRes(alignment.getWidth() - 1);
1183 for (int t = 0; t < tmp.size(); t++)
1185 selectionGroup.addSequence((SequenceI) tmp.elementAt(t), false);
1187 firePropertyChange("alignment", null, alignment.getSequences());
1191 if (alignment.getHiddenSequences().getSize() < 1)
1193 hasHiddenRows = false;
1196 public void showColumn(int col)
1198 colSel.revealHiddenColumns(col);
1199 if (colSel.getHiddenColumns() == null)
1201 hasHiddenColumns = false;
1205 public void showAllHiddenColumns()
1207 colSel.revealAllHiddenColumns();
1208 hasHiddenColumns = false;
1211 public void showAllHiddenSeqs()
1213 if (alignment.getHiddenSequences().getSize() > 0)
1215 if (selectionGroup == null)
1217 selectionGroup = new SequenceGroup();
1218 selectionGroup.setEndRes(alignment.getWidth() - 1);
1220 Vector tmp = alignment.getHiddenSequences().showAll(
1221 hiddenRepSequences);
1222 for (int t = 0; t < tmp.size(); t++)
1224 selectionGroup.addSequence((SequenceI) tmp.elementAt(t), false);
1226 firePropertyChange("alignment", null, alignment.getSequences());
1227 hasHiddenRows = false;
1228 hiddenRepSequences = null;
1233 public int adjustForHiddenSeqs(int alignmentIndex)
1235 return alignment.getHiddenSequences().adjustForHiddenSeqs(
1240 * This method returns the a new SequenceI [] with the selection sequence and
1241 * start and end points adjusted
1245 public SequenceI[] getSelectionAsNewSequence()
1247 SequenceI[] sequences;
1249 if (selectionGroup == null)
1251 sequences = alignment.getSequencesArray();
1255 sequences = selectionGroup.getSelectionAsNewSequences(alignment);
1262 * get the currently selected sequence objects or all the sequences in the
1265 * @return array of references to sequence objects
1267 public SequenceI[] getSequenceSelection()
1269 SequenceI[] sequences = null;
1270 if (selectionGroup != null)
1272 sequences = selectionGroup.getSequencesInOrder(alignment);
1274 if (sequences == null)
1276 sequences = alignment.getSequencesArray();
1282 * This method returns the visible alignment as text, as seen on the GUI, ie
1283 * if columns are hidden they will not be returned in the result. Use this for
1284 * calculating trees, PCA, redundancy etc on views which contain hidden
1289 public jalview.datamodel.CigarArray getViewAsCigars(
1290 boolean selectedRegionOnly)
1292 return new jalview.datamodel.CigarArray(alignment, (hasHiddenColumns ? colSel : null), (selectedRegionOnly ? selectionGroup : null));
1296 * return a compact representation of the current alignment selection to pass
1297 * to an analysis function
1299 * @param selectedOnly
1300 * boolean true to just return the selected view
1301 * @return AlignmentView
1303 jalview.datamodel.AlignmentView getAlignmentView(boolean selectedOnly)
1305 return getAlignmentView(selectedOnly, false);
1309 * return a compact representation of the current alignment selection to pass
1310 * to an analysis function
1312 * @param selectedOnly
1313 * boolean true to just return the selected view
1315 * boolean true to annotate the alignment view with groups on the alignment (and intersecting with selected region if selectedOnly is true)
1316 * @return AlignmentView
1318 public jalview.datamodel.AlignmentView getAlignmentView(boolean selectedOnly, boolean markGroups)
1320 return new AlignmentView(alignment, colSel, selectionGroup, hasHiddenColumns, selectedOnly, markGroups);
1323 * This method returns the visible alignment as text, as seen on the GUI, ie
1324 * if columns are hidden they will not be returned in the result. Use this for
1325 * calculating trees, PCA, redundancy etc on views which contain hidden
1330 public String[] getViewAsString(boolean selectedRegionOnly)
1332 String[] selection = null;
1333 SequenceI[] seqs = null;
1335 int start = 0, end = 0;
1336 if (selectedRegionOnly && selectionGroup != null)
1338 iSize = selectionGroup.getSize();
1339 seqs = selectionGroup.getSequencesInOrder(alignment);
1340 start = selectionGroup.getStartRes();
1341 end = selectionGroup.getEndRes() + 1;
1345 iSize = alignment.getHeight();
1346 seqs = alignment.getSequencesArray();
1347 end = alignment.getWidth();
1350 selection = new String[iSize];
1352 for (i = 0; i < iSize; i++)
1354 if (hasHiddenColumns)
1356 StringBuffer visibleSeq = new StringBuffer();
1357 Vector regions = colSel.getHiddenColumns();
1359 int blockStart = start, blockEnd = end;
1361 int hideStart, hideEnd;
1363 for (int j = 0; j < regions.size(); j++)
1365 region = (int[]) regions.elementAt(j);
1366 hideStart = region[0];
1367 hideEnd = region[1];
1369 if (hideStart < start)
1374 blockStart = Math.min(blockStart, hideEnd + 1);
1375 blockEnd = Math.min(blockEnd, hideStart);
1377 if (blockStart > blockEnd)
1382 visibleSeq.append(seqs[i].getSequence(blockStart, blockEnd));
1384 blockStart = hideEnd + 1;
1388 if (end > blockStart)
1390 visibleSeq.append(seqs[i].getSequence(blockStart, end));
1393 selection[i] = visibleSeq.toString();
1397 selection[i] = seqs[i].getSequenceAsString(start, end);
1404 public boolean getShowHiddenMarkers()
1406 return showHiddenMarkers;
1409 public void setShowHiddenMarkers(boolean show)
1411 showHiddenMarkers = show;
1414 public Color getSequenceColour(SequenceI seq)
1416 if (sequenceColours == null || !sequenceColours.containsKey(seq))
1422 return (Color) sequenceColours.get(seq);
1426 public void setSequenceColour(SequenceI seq, Color col)
1428 if (sequenceColours == null)
1430 sequenceColours = new Hashtable();
1435 sequenceColours.remove(seq);
1439 sequenceColours.put(seq, col);
1443 public String getSequenceSetId()
1445 if (sequenceSetID == null)
1447 sequenceSetID = alignment.hashCode() + "";
1450 return sequenceSetID;
1453 * unique viewId for synchronizing state (e.g. with stored Jalview Project)
1456 private String viewId = null;
1458 public String getViewId()
1462 viewId = this.getSequenceSetId() + "." + this.hashCode() + "";
1467 public void alignmentChanged(AlignmentPanel ap)
1469 alignment.padGaps();
1471 if (hconsensus != null && autocalculateConsensus)
1473 updateConsensus(ap);
1474 updateConservation(ap);
1477 // Reset endRes of groups if beyond alignment width
1478 int alWidth = alignment.getWidth();
1479 Vector groups = alignment.getGroups();
1482 for (int i = 0; i < groups.size(); i++)
1484 SequenceGroup sg = (SequenceGroup) groups.elementAt(i);
1485 if (sg.getEndRes() > alWidth)
1487 sg.setEndRes(alWidth - 1);
1492 if (selectionGroup != null && selectionGroup.getEndRes() > alWidth)
1494 selectionGroup.setEndRes(alWidth - 1);
1497 resetAllColourSchemes();
1499 // AW alignment.adjustSequenceAnnotations();
1502 void resetAllColourSchemes()
1504 ColourSchemeI cs = globalColourScheme;
1507 if (cs instanceof ClustalxColourScheme)
1509 ((ClustalxColourScheme) cs).resetClustalX(alignment.getSequences(),
1510 alignment.getWidth());
1513 cs.setConsensus(hconsensus);
1514 if (cs.conservationApplied())
1516 Alignment al = (Alignment) alignment;
1517 Conservation c = new Conservation("All",
1518 ResidueProperties.propHash, 3, al.getSequences(), 0,
1521 c.verdict(false, ConsPercGaps);
1523 cs.setConservation(c);
1527 int s, sSize = alignment.getGroups().size();
1528 for (s = 0; s < sSize; s++)
1530 SequenceGroup sg = (SequenceGroup) alignment.getGroups().elementAt(s);
1531 if (sg.cs != null && sg.cs instanceof ClustalxColourScheme)
1533 ((ClustalxColourScheme) sg.cs).resetClustalX(
1534 sg.getSequences(hiddenRepSequences), sg.getWidth());
1536 sg.recalcConservation();
1540 boolean centreColumnLabels;
1542 public boolean getCentreColumnLabels()
1544 return centreColumnLabels;
1547 public void updateSequenceIdColours()
1549 Vector groups = alignment.getGroups();
1550 for (int ig = 0, igSize = groups.size(); ig < igSize; ig++)
1552 SequenceGroup sg = (SequenceGroup) groups.elementAt(ig);
1553 if (sg.idColour != null)
1555 Vector sqs = sg.getSequences(hiddenRepSequences);
1556 for (int s = 0, sSize = sqs.size(); s < sSize; s++)
1558 this.setSequenceColour((SequenceI) sqs.elementAt(s), sg.idColour);
1564 public boolean followHighlight = false;
1566 public boolean getFollowHighlight()
1568 return followHighlight;
1571 public boolean followSelection = true;
1574 * @return true if view selection should always follow the selections
1575 * broadcast by other selection sources
1577 public boolean getFollowSelection()
1579 return followSelection;
1582 private long sgrouphash = -1, colselhash = -1;
1585 * checks current SelectionGroup against record of last hash value, and
1588 * @return true if SelectionGroup changed since last call
1590 boolean isSelectionGroupChanged()
1592 int hc = (selectionGroup == null) ? -1 : selectionGroup.hashCode();
1593 if (hc != sgrouphash)
1602 * checks current colsel against record of last hash value, and updates
1605 * @return true if colsel changed since last call
1607 boolean isColSelChanged()
1609 int hc = (colSel == null) ? -1 : colSel.hashCode();
1610 if (hc != colselhash)
1617 public void sendSelection()
1619 jalview.structure.StructureSelectionManager
1620 .getStructureSelectionManager().sendSelection(
1621 new SequenceGroup(getSelectionGroup()),
1622 new ColumnSelection(getColumnSelection()), this);
1629 * show non-conserved residues only
1631 public boolean showUnconserved = false;
1634 * when set, alignment should be reordered according to a newly opened tree
1636 public boolean sortByTree = false;
1639 * @return the showUnconserved
1641 public boolean getShowunconserved()
1643 return showUnconserved;
1647 * @param showNonconserved
1648 * the showUnconserved to set
1650 public void setShowunconserved(boolean displayNonconserved)
1652 this.showUnconserved = displayNonconserved;
1656 * should conservation rows be shown for groups
1658 boolean showGroupConservation = false;
1661 * should consensus rows be shown for groups
1663 boolean showGroupConsensus = false;
1666 * should consensus profile be rendered by default
1668 public boolean showSequenceLogo = false;
1671 * should consensus histograms be rendered by default
1673 public boolean showConsensusHistogram = true;
1676 * @return the showConsensusProfile
1678 public boolean isShowSequenceLogo()
1680 return showSequenceLogo;
1684 * @param showSequenceLogo
1687 public void setShowSequenceLogo(boolean showSequenceLogo)
1689 if (showSequenceLogo != this.showSequenceLogo)
1691 // TODO: decouple settings setting from calculation when refactoring
1692 // annotation update method from alignframe to viewport
1693 this.showSequenceLogo = showSequenceLogo;
1694 if (consensusThread != null)
1696 consensusThread.updateAnnotation();
1699 this.showSequenceLogo = showSequenceLogo;
1703 * @param showConsensusHistogram
1704 * the showConsensusHistogram to set
1706 public void setShowConsensusHistogram(boolean showConsensusHistogram)
1708 this.showConsensusHistogram = showConsensusHistogram;
1712 * @return the showGroupConservation
1714 public boolean isShowGroupConservation()
1716 return showGroupConservation;
1720 * @param showGroupConservation
1721 * the showGroupConservation to set
1723 public void setShowGroupConservation(boolean showGroupConservation)
1725 this.showGroupConservation = showGroupConservation;
1729 * @return the showGroupConsensus
1731 public boolean isShowGroupConsensus()
1733 return showGroupConsensus;
1737 * @param showGroupConsensus
1738 * the showGroupConsensus to set
1740 public void setShowGroupConsensus(boolean showGroupConsensus)
1742 this.showGroupConsensus = showGroupConsensus;
1747 * @return flag to indicate if the consensus histogram should be rendered by
1750 public boolean isShowConsensusHistogram()
1752 return this.showConsensusHistogram;
1756 * synthesize a column selection if none exists so it covers the given
1757 * selection group. if wholewidth is false, no column selection is made if the
1758 * selection group covers the whole alignment width.
1763 public void expandColSelection(SequenceGroup sg, boolean wholewidth)
1767 && (sgs = sg.getStartRes()) >= 0
1768 && sg.getStartRes() <= (sge = sg.getEndRes())
1769 && (colSel == null || colSel.getSelected() == null || colSel
1770 .getSelected().size() == 0))
1772 if (!wholewidth && alignment.getWidth() == (1 + sge - sgs))
1779 colSel = new ColumnSelection();
1781 for (int cspos = sg.getStartRes(); cspos <= sg.getEndRes(); cspos++)
1783 colSel.addElement(cspos);