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/>.
19 * Jalview - A Sequence Alignment Editor and Viewer
20 * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
22 * This program is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU General Public License
24 * as published by the Free Software Foundation; either version 2
25 * of the License, or (at your option) any later version.
27 * This program is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 * GNU General Public License for more details.
32 * You should have received a copy of the GNU General Public License
33 * along with this program; if not, write to the Free Software
34 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
42 import jalview.analysis.*;
43 import jalview.api.StructureSelectionManagerProvider;
47 import jalview.datamodel.*;
49 import jalview.schemes.*;
50 import jalview.structure.SelectionSource;
51 import jalview.structure.StructureSelectionManager;
52 import jalview.structure.VamsasSource;
58 * @version $Revision: 1.141 $
60 public class AlignViewport implements SelectionSource, VamsasSource
62 private static final int RIGHT_JUSTIFY = 1;
72 boolean showJVSuffix = true;
74 boolean showText = true;
76 boolean showColourText = false;
78 boolean showBoxes = true;
80 boolean wrapAlignment = false;
82 boolean renderGaps = true;
84 boolean showSequenceFeatures = false;
86 boolean showAnnotation = true;
88 boolean colourAppliesToAllGroups = true;
90 ColourSchemeI globalColourScheme = null;
92 boolean conservationColourSelected = false;
94 boolean abovePIDThreshold = false;
96 SequenceGroup selectionGroup;
102 boolean validCharWidth;
108 boolean seqNameItalics;
110 AlignmentI alignment;
112 ColumnSelection colSel = new ColumnSelection();
118 NJTree currentTree = null;
120 boolean scaleAboveWrapped = false;
122 boolean scaleLeftWrapped = true;
124 boolean scaleRightWrapped = true;
126 boolean hasHiddenColumns = false;
128 boolean hasHiddenRows = false;
130 boolean showHiddenMarkers = true;
132 boolean cursorMode = false;
135 * Keys are the feature types which are currently visible. Note: Values are
138 Hashtable featuresDisplayed = null;
141 public Hashtable[] hconsensus;
143 public Hashtable[] hStrucConsensus;
145 AlignmentAnnotation consensus;
147 AlignmentAnnotation strucConsensus;
149 AlignmentAnnotation conservation;
151 AlignmentAnnotation quality;
153 AlignmentAnnotation[] groupConsensus;
155 AlignmentAnnotation[] groupConservation;
157 boolean autoCalculateConsensus = true;
159 boolean autoCalculateStrucConsensus = true;
162 public int ConsPercGaps = 25; // JBPNote : This should be a scalable property!
164 // JBPNote Prolly only need this in the applet version.
165 private java.beans.PropertyChangeSupport changeSupport = new java.beans.PropertyChangeSupport(
168 boolean ignoreGapsInConsensusCalculation = false;
170 boolean isDataset = false;
172 boolean antiAlias = false;
174 boolean padGaps = false;
176 Rectangle explodedPosition;
180 String sequenceSetID;
182 boolean gatherViewsHere = false;
184 Stack historyList = new Stack();
186 Stack redoList = new Stack();
188 Hashtable sequenceColours;
190 int thresholdTextColour = 0;
192 Color textColour = Color.black;
194 Color textColour2 = Color.white;
196 boolean rightAlignIds = false;
198 Hashtable hiddenRepSequences;
203 * Creates a new AlignViewport object.
208 public AlignViewport(AlignmentI al)
215 * Create a new AlignViewport object with a specific sequence set ID
219 * (may be null - but potential for ambiguous constructor exception)
221 public AlignViewport(AlignmentI al, String seqsetid)
223 this(al, seqsetid, null);
226 public AlignViewport(AlignmentI al, String seqsetid, String viewid)
228 sequenceSetID = seqsetid;
230 // TODO remove these once 2.4.VAMSAS release finished
231 if (Cache.log != null && Cache.log.isDebugEnabled() && seqsetid != null)
233 Cache.log.debug("Setting viewport's sequence set id : "
236 if (Cache.log != null && Cache.log.isDebugEnabled() && viewId != null)
238 Cache.log.debug("Setting viewport's view id : " + viewId);
245 * Create a new AlignViewport with hidden regions
249 * @param hiddenColumns
252 public AlignViewport(AlignmentI al, ColumnSelection hiddenColumns)
255 if (hiddenColumns != null)
257 this.colSel = hiddenColumns;
258 if (hiddenColumns.getHiddenColumns() != null
259 && hiddenColumns.getHiddenColumns().size() > 0)
261 hasHiddenColumns = true;
265 hasHiddenColumns = false;
272 * New viewport with hidden columns and an existing sequence set id
275 * @param hiddenColumns
279 public AlignViewport(AlignmentI al, ColumnSelection hiddenColumns,
282 this(al, hiddenColumns, seqsetid, null);
286 * New viewport with hidden columns and an existing sequence set id and viewid
289 * @param hiddenColumns
295 public AlignViewport(AlignmentI al, ColumnSelection hiddenColumns,
296 String seqsetid, String viewid)
298 sequenceSetID = seqsetid;
300 // TODO remove these once 2.4.VAMSAS release finished
301 if (Cache.log != null && Cache.log.isDebugEnabled() && seqsetid != null)
303 Cache.log.debug("Setting viewport's sequence set id : "
306 if (Cache.log != null && Cache.log.isDebugEnabled() && viewId != null)
308 Cache.log.debug("Setting viewport's view id : " + viewId);
311 if (hiddenColumns != null)
313 this.colSel = hiddenColumns;
314 if (hiddenColumns.getHiddenColumns() != null
315 && hiddenColumns.getHiddenColumns().size() > 0)
317 hasHiddenColumns = true;
321 hasHiddenColumns = false;
330 this.endRes = alignment.getWidth() - 1;
332 this.endSeq = alignment.getHeight() - 1;
334 antiAlias = Cache.getDefault("ANTI_ALIAS", false);
336 showJVSuffix = Cache.getDefault("SHOW_JVSUFFIX", true);
337 showAnnotation = Cache.getDefault("SHOW_ANNOTATIONS", true);
339 rightAlignIds = Cache.getDefault("RIGHT_ALIGN_IDS", false);
340 centreColumnLabels = Cache.getDefault("CENTRE_COLUMN_LABELS", false);
341 autoCalculateConsensus = Cache.getDefault("AUTO_CALC_CONSENSUS", true);
343 padGaps = Cache.getDefault("PAD_GAPS", true);
344 shownpfeats = Cache.getDefault("SHOW_NPFEATS_TOOLTIP", true);
345 showdbrefs = Cache.getDefault("SHOW_DBREFS_TOOLTIP", true);
347 String fontName = Cache.getDefault("FONT_NAME", "SansSerif");
348 String fontStyle = Cache.getDefault("FONT_STYLE", Font.PLAIN + "");
349 String fontSize = Cache.getDefault("FONT_SIZE", "10");
351 seqNameItalics = Cache.getDefault("ID_ITALICS", true);
355 if (fontStyle.equals("bold"))
359 else if (fontStyle.equals("italic"))
364 setFont(new Font(fontName, style, Integer.parseInt(fontSize)));
367 .setGapCharacter(Cache.getDefault("GAP_SYMBOL", "-").charAt(0));
369 // We must set conservation and consensus before setting colour,
370 // as Blosum and Clustal require this to be done
371 if (hconsensus == null && !isDataset)
373 if (!alignment.isNucleotide())
375 conservation = new AlignmentAnnotation("Conservation",
376 "Conservation of total alignment less than " + ConsPercGaps
377 + "% gaps", new Annotation[1], 0f, 11f,
378 AlignmentAnnotation.BAR_GRAPH);
379 conservation.hasText = true;
380 conservation.autoCalculated = true;
382 if (Cache.getDefault("SHOW_CONSERVATION", true))
384 alignment.addAnnotation(conservation);
387 if (Cache.getDefault("SHOW_QUALITY", true))
389 quality = new AlignmentAnnotation("Quality",
390 "Alignment Quality based on Blosum62 scores",
391 new Annotation[1], 0f, 11f, AlignmentAnnotation.BAR_GRAPH);
392 quality.hasText = true;
393 quality.autoCalculated = true;
395 alignment.addAnnotation(quality);
397 showGroupConservation = Cache.getDefault("SHOW_GROUP_CONSERVATION",
404 showConsensusHistogram = Cache.getDefault("SHOW_CONSENSUS_HISTOGRAM",
406 showSequenceLogo = Cache.getDefault("SHOW_CONSENSUS_LOGO", false);
407 showGroupConsensus = Cache.getDefault("SHOW_GROUP_CONSENSUS", false);
408 // TODO: add menu option action that nulls or creates consensus object
409 // depending on if the user wants to see the annotation or not in a
410 // specific alignment
411 consensus = new AlignmentAnnotation("Consensus", "PID",
412 new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH);
413 consensus.hasText = true;
414 consensus.autoCalculated = true;
416 // TODO check if this can done accordingly
417 strucConsensus = new AlignmentAnnotation("StrucConsensus", "PID",
418 new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH);
419 strucConsensus.hasText = true;
420 strucConsensus.autoCalculated = true;
422 if (Cache.getDefault("SHOW_IDENTITY", true))
424 alignment.addAnnotation(consensus);
425 // TODO: Make own if for structure
426 alignment.addAnnotation(strucConsensus);
431 if (jalview.bin.Cache.getProperty("DEFAULT_COLOUR") != null)
433 globalColourScheme = ColourSchemeProperty.getColour(alignment,
434 jalview.bin.Cache.getProperty("DEFAULT_COLOUR"));
436 if (globalColourScheme instanceof UserColourScheme)
438 globalColourScheme = UserDefinedColours.loadDefaultColours();
439 ((UserColourScheme) globalColourScheme).setThreshold(0,
440 getIgnoreGapsConsensus());
443 if (globalColourScheme != null)
445 globalColourScheme.setConsensus(hconsensus);
449 wrapAlignment = jalview.bin.Cache.getDefault("WRAP_ALIGNMENT", false);
450 showUnconserved = jalview.bin.Cache.getDefault("SHOW_UNCONSERVED",
452 sortByTree = jalview.bin.Cache.getDefault("SORT_BY_TREE", false);
453 followSelection = jalview.bin.Cache.getDefault("FOLLOW_SELECTIONS",
461 * features are displayed if true
463 public void setShowSequenceFeatures(boolean b)
465 showSequenceFeatures = b;
468 public boolean getShowSequenceFeatures()
470 return showSequenceFeatures;
473 ConservationThread conservationThread;
475 ConsensusThread consensusThread;
477 StrucConsensusThread strucConsensusThread;
479 boolean consUpdateNeeded = false;
481 static boolean UPDATING_CONSENSUS = false;
483 static boolean UPDATING_STRUC_CONSENSUS = false;
485 static boolean UPDATING_CONSERVATION = false;
487 boolean updatingConsensus = false;
489 boolean updatingStrucConsensus = false;
491 boolean updatingConservation = false;
494 * centre columnar annotation labels in displayed alignment annotation TODO:
495 * add to jalviewXML and annotation display settings
497 boolean centreColumnLabels = false;
499 private boolean showdbrefs;
501 private boolean shownpfeats;
504 * trigger update of conservation annotation
506 public void updateConservation(final AlignmentPanel ap)
508 // see note in mantis : issue number 8585
509 if (alignment.isNucleotide() || conservation == null
510 || !autoCalculateConsensus)
515 conservationThread = new ConservationThread(this, ap);
516 conservationThread.start();
520 * trigger update of consensus annotation
522 public void updateConsensus(final AlignmentPanel ap)
524 // see note in mantis : issue number 8585
525 if (consensus == null || !autoCalculateConsensus)
529 consensusThread = new ConsensusThread(ap);
530 consensusThread.start();
533 class ConsensusThread extends Thread
537 public ConsensusThread(AlignmentPanel ap)
544 updatingConsensus = true;
545 while (UPDATING_CONSENSUS)
551 ap.paintAlignment(false);
555 } catch (Exception ex)
557 ex.printStackTrace();
561 UPDATING_CONSENSUS = true;
565 int aWidth = (alignment != null) ? alignment.getWidth() : -1; // null
571 updatingConsensus = false;
572 UPDATING_CONSENSUS = false;
576 consensus.annotations = null;
577 consensus.annotations = new Annotation[aWidth];
579 hconsensus = new Hashtable[aWidth];
580 AAFrequency.calculate(alignment.getSequencesArray(), 0, alignment
581 .getWidth(), hconsensus, true);
582 updateAnnotation(true);
583 if (globalColourScheme != null)
585 globalColourScheme.setConsensus(hconsensus);
588 } catch (OutOfMemoryError error)
590 alignment.deleteAnnotation(consensus);
594 new OOMWarning("calculating consensus", error);
596 UPDATING_CONSENSUS = false;
597 updatingConsensus = false;
601 ap.paintAlignment(true);
606 * update the consensus annotation from the sequence profile data using
607 * current visualization settings.
609 public void updateAnnotation()
611 updateAnnotation(false);
614 protected void updateAnnotation(boolean immediate)
616 // TODO: make calls thread-safe, so if another thread calls this method,
617 // it will either return or wait until one calculation is finished.
619 || (!updatingConsensus && consensus != null && hconsensus != null))
621 AAFrequency.completeConsensus(consensus, hconsensus, 0,
622 hconsensus.length, ignoreGapsInConsensusCalculation,
628 // --------START Structure Conservation
629 public void updateStrucConsensus(final AlignmentPanel ap)
631 // see note in mantis : issue number 8585
632 if (strucConsensus == null || !autoCalculateStrucConsensus)
636 strucConsensusThread = new StrucConsensusThread(ap);
637 strucConsensusThread.start();
640 class StrucConsensusThread extends Thread
644 public StrucConsensusThread(AlignmentPanel ap)
651 updatingStrucConsensus = true;
652 while (UPDATING_STRUC_CONSENSUS)
658 ap.paintAlignment(false);
662 } catch (Exception ex)
664 ex.printStackTrace();
668 UPDATING_STRUC_CONSENSUS = true;
672 int aWidth = (alignment != null) ? alignment.getWidth() : -1; // null
678 updatingStrucConsensus = false;
679 UPDATING_STRUC_CONSENSUS = false;
683 strucConsensus.annotations = null;
684 strucConsensus.annotations = new Annotation[aWidth];
686 hStrucConsensus = new Hashtable[aWidth];
688 AlignmentAnnotation[] aa = ap.av.getAlignment()
689 .getAlignmentAnnotation();
690 AlignmentAnnotation rnaStruc = null;
691 for (int i = 0; i < aa.length; i++)
693 if (aa[i].getRNAStruc() != null)
700 AlignmentAnnotation rna = ap.av.getAlignment()
701 .getAlignmentAnnotation()[0];
702 StructureFrequency.calculate(alignment.getSequencesArray(), 0,
703 alignment.getWidth(), hStrucConsensus, true, rnaStruc);
704 // TODO AlignmentAnnotation rnaStruc!!!
705 updateAnnotation(true);
706 if (globalColourScheme != null)
708 globalColourScheme.setConsensus(hStrucConsensus);
711 } catch (OutOfMemoryError error)
713 alignment.deleteAnnotation(strucConsensus);
715 strucConsensus = null;
716 hStrucConsensus = null;
717 new OOMWarning("calculating structure consensus", error);
719 UPDATING_STRUC_CONSENSUS = false;
720 updatingStrucConsensus = false;
724 ap.paintAlignment(true);
729 * update the consensus annotation from the sequence profile data using
730 * current visualization settings.
732 public void updateAnnotation()
734 updateAnnotation(false);
737 protected void updateAnnotation(boolean immediate)
739 // TODO: make calls thread-safe, so if another thread calls this method,
740 // it will either return or wait until one calculation is finished.
742 || (!updatingStrucConsensus && strucConsensus != null && hStrucConsensus != null))
744 StructureFrequency.completeConsensus(strucConsensus,
745 hStrucConsensus, 0, hStrucConsensus.length, false,
751 // --------END Structure Conservation
754 * get the consensus sequence as displayed under the PID consensus annotation
757 * @return consensus sequence as a new sequence object
759 public SequenceI getConsensusSeq()
761 if (consensus == null)
763 updateConsensus(null);
765 if (consensus == null)
769 StringBuffer seqs = new StringBuffer();
770 for (int i = 0; i < consensus.annotations.length; i++)
772 if (consensus.annotations[i] != null)
774 if (consensus.annotations[i].description.charAt(0) == '[')
776 seqs.append(consensus.annotations[i].description.charAt(1));
780 seqs.append(consensus.annotations[i].displayCharacter);
785 SequenceI sq = new Sequence("Consensus", seqs.toString());
786 sq.setDescription("Percentage Identity Consensus "
787 + ((ignoreGapsInConsensusCalculation) ? " without gaps" : ""));
794 * @return null or the currently selected sequence region
796 public SequenceGroup getSelectionGroup()
798 return selectionGroup;
802 * Set the selection group for this window.
805 * - group holding references to sequences in this alignment view
808 public void setSelectionGroup(SequenceGroup sg)
816 * @return true if conservation based shading is enabled
818 public boolean getConservationSelected()
820 return conservationColourSelected;
827 * enable conservation based shading
829 public void setConservationSelected(boolean b)
831 conservationColourSelected = b;
837 * @return true if percent identity threshold is applied to shading
839 public boolean getAbovePIDThreshold()
841 return abovePIDThreshold;
849 * indicate if percent identity threshold is applied to shading
851 public void setAbovePIDThreshold(boolean b)
853 abovePIDThreshold = b;
859 * @return DOCUMENT ME!
861 public int getStartRes()
869 * @return DOCUMENT ME!
871 public int getEndRes()
879 * @return DOCUMENT ME!
881 public int getStartSeq()
892 public void setGlobalColourScheme(ColourSchemeI cs)
894 globalColourScheme = cs;
900 * @return DOCUMENT ME!
902 public ColourSchemeI getGlobalColourScheme()
904 return globalColourScheme;
913 public void setStartRes(int res)
924 public void setStartSeq(int seq)
935 public void setEndRes(int res)
937 if (res > (alignment.getWidth() - 1))
939 // log.System.out.println(" Corrected res from " + res + " to maximum " +
940 // (alignment.getWidth()-1));
941 res = alignment.getWidth() - 1;
958 public void setEndSeq(int seq)
960 if (seq > alignment.getHeight())
962 seq = alignment.getHeight();
976 * @return DOCUMENT ME!
978 public int getEndSeq()
989 public void setFont(Font f)
993 Container c = new Container();
995 java.awt.FontMetrics fm = c.getFontMetrics(font);
996 setCharHeight(fm.getHeight());
997 setCharWidth(fm.charWidth('M'));
998 validCharWidth = true;
1004 * @return DOCUMENT ME!
1006 public Font getFont()
1017 public void setCharWidth(int w)
1025 * @return DOCUMENT ME!
1027 public int getCharWidth()
1038 public void setCharHeight(int h)
1040 this.charHeight = h;
1046 * @return DOCUMENT ME!
1048 public int getCharHeight()
1059 public void setWrappedWidth(int w)
1061 this.wrappedWidth = w;
1067 * @return DOCUMENT ME!
1069 public int getWrappedWidth()
1071 return wrappedWidth;
1077 * @return DOCUMENT ME!
1079 public AlignmentI getAlignment()
1090 public void setAlignment(AlignmentI align)
1092 if (alignment != null && alignment.getCodonFrames() != null)
1094 StructureSelectionManager.getStructureSelectionManager(
1095 Desktop.instance).removeMappings(alignment.getCodonFrames());
1097 this.alignment = align;
1098 if (alignment.getCodonFrames() != null)
1100 StructureSelectionManager.getStructureSelectionManager(
1101 Desktop.instance).addMappings(alignment.getCodonFrames());
1111 public void setWrapAlignment(boolean state)
1113 wrapAlignment = state;
1122 public void setShowText(boolean state)
1133 public void setRenderGaps(boolean state)
1141 * @return DOCUMENT ME!
1143 public boolean getColourText()
1145 return showColourText;
1154 public void setColourText(boolean state)
1156 showColourText = state;
1165 public void setShowBoxes(boolean state)
1173 * @return DOCUMENT ME!
1175 public boolean getWrapAlignment()
1177 return wrapAlignment;
1183 * @return DOCUMENT ME!
1185 public boolean getShowText()
1193 * @return DOCUMENT ME!
1195 public boolean getShowBoxes()
1203 * @return DOCUMENT ME!
1205 public char getGapCharacter()
1207 return getAlignment().getGapCharacter();
1216 public void setGapCharacter(char gap)
1218 if (getAlignment() != null)
1220 getAlignment().setGapCharacter(gap);
1230 public void setThreshold(int thresh)
1238 * @return DOCUMENT ME!
1240 public int getThreshold()
1251 public void setIncrement(int inc)
1259 * @return DOCUMENT ME!
1261 public int getIncrement()
1269 * @return DOCUMENT ME!
1271 public ColumnSelection getColumnSelection()
1282 public void setCurrentTree(NJTree tree)
1290 * @return DOCUMENT ME!
1292 public NJTree getCurrentTree()
1303 public void setColourAppliesToAllGroups(boolean b)
1305 colourAppliesToAllGroups = b;
1311 * @return DOCUMENT ME!
1313 public boolean getColourAppliesToAllGroups()
1315 return colourAppliesToAllGroups;
1321 * @return DOCUMENT ME!
1323 public boolean getShowJVSuffix()
1325 return showJVSuffix;
1334 public void setShowJVSuffix(boolean b)
1342 * @return DOCUMENT ME!
1344 public boolean getShowAnnotation()
1346 return showAnnotation;
1355 public void setShowAnnotation(boolean b)
1363 * @return DOCUMENT ME!
1365 public boolean getScaleAboveWrapped()
1367 return scaleAboveWrapped;
1373 * @return DOCUMENT ME!
1375 public boolean getScaleLeftWrapped()
1377 return scaleLeftWrapped;
1383 * @return DOCUMENT ME!
1385 public boolean getScaleRightWrapped()
1387 return scaleRightWrapped;
1396 public void setScaleAboveWrapped(boolean b)
1398 scaleAboveWrapped = b;
1407 public void setScaleLeftWrapped(boolean b)
1409 scaleLeftWrapped = b;
1418 public void setScaleRightWrapped(boolean b)
1420 scaleRightWrapped = b;
1424 * Property change listener for changes in alignment
1429 public void addPropertyChangeListener(
1430 java.beans.PropertyChangeListener listener)
1432 changeSupport.addPropertyChangeListener(listener);
1441 public void removePropertyChangeListener(
1442 java.beans.PropertyChangeListener listener)
1444 changeSupport.removePropertyChangeListener(listener);
1448 * Property change listener for changes in alignment
1457 public void firePropertyChange(String prop, Object oldvalue,
1460 changeSupport.firePropertyChange(prop, oldvalue, newvalue);
1463 public void setIgnoreGapsConsensus(boolean b, AlignmentPanel ap)
1465 ignoreGapsInConsensusCalculation = b;
1466 updateConsensus(ap);
1467 if (globalColourScheme != null)
1469 globalColourScheme.setThreshold(globalColourScheme.getThreshold(),
1470 ignoreGapsInConsensusCalculation);
1474 public boolean getIgnoreGapsConsensus()
1476 return ignoreGapsInConsensusCalculation;
1479 public void setDataset(boolean b)
1484 public boolean isDataset()
1489 public void hideSelectedColumns()
1491 if (colSel.size() < 1)
1496 colSel.hideSelectedColumns();
1497 setSelectionGroup(null);
1499 hasHiddenColumns = true;
1502 public void hideColumns(int start, int end)
1506 colSel.hideColumns(start);
1510 colSel.hideColumns(start, end);
1513 hasHiddenColumns = true;
1516 public void hideRepSequences(SequenceI repSequence, SequenceGroup sg)
1518 int sSize = sg.getSize();
1524 if (hiddenRepSequences == null)
1526 hiddenRepSequences = new Hashtable();
1529 hiddenRepSequences.put(repSequence, sg);
1531 // Hide all sequences except the repSequence
1532 SequenceI[] seqs = new SequenceI[sSize - 1];
1534 for (int i = 0; i < sSize; i++)
1536 if (sg.getSequenceAt(i) != repSequence)
1538 if (index == sSize - 1)
1543 seqs[index++] = sg.getSequenceAt(i);
1546 sg.setSeqrep(repSequence);
1547 sg.setHidereps(true);
1552 public void hideAllSelectedSeqs()
1554 if (selectionGroup == null || selectionGroup.getSize() < 1)
1559 SequenceI[] seqs = selectionGroup.getSequencesInOrder(alignment);
1563 setSelectionGroup(null);
1566 public void hideSequence(SequenceI[] seq)
1570 for (int i = 0; i < seq.length; i++)
1572 alignment.getHiddenSequences().hideSequence(seq[i]);
1574 hasHiddenRows = true;
1575 firePropertyChange("alignment", null, alignment.getSequences());
1579 public void showSequence(int index)
1581 Vector tmp = alignment.getHiddenSequences().showSequence(index,
1582 hiddenRepSequences);
1585 if (selectionGroup == null)
1587 selectionGroup = new SequenceGroup();
1588 selectionGroup.setEndRes(alignment.getWidth() - 1);
1591 for (int t = 0; t < tmp.size(); t++)
1593 selectionGroup.addSequence((SequenceI) tmp.elementAt(t), false);
1595 firePropertyChange("alignment", null, alignment.getSequences());
1599 if (alignment.getHiddenSequences().getSize() < 1)
1601 hasHiddenRows = false;
1605 public void showColumn(int col)
1607 colSel.revealHiddenColumns(col);
1608 if (colSel.getHiddenColumns() == null)
1610 hasHiddenColumns = false;
1614 public void showAllHiddenColumns()
1616 colSel.revealAllHiddenColumns();
1617 hasHiddenColumns = false;
1620 public void showAllHiddenSeqs()
1622 if (alignment.getHiddenSequences().getSize() > 0)
1624 if (selectionGroup == null)
1626 selectionGroup = new SequenceGroup();
1627 selectionGroup.setEndRes(alignment.getWidth() - 1);
1629 Vector tmp = alignment.getHiddenSequences().showAll(
1630 hiddenRepSequences);
1631 for (int t = 0; t < tmp.size(); t++)
1633 selectionGroup.addSequence((SequenceI) tmp.elementAt(t), false);
1635 firePropertyChange("alignment", null, alignment.getSequences());
1637 hasHiddenRows = false;
1638 hiddenRepSequences = null;
1642 public void invertColumnSelection()
1644 colSel.invertColumnSelection(0, alignment.getWidth());
1647 public int adjustForHiddenSeqs(int alignmentIndex)
1649 return alignment.getHiddenSequences().adjustForHiddenSeqs(
1654 * This method returns an array of new SequenceI objects derived from the
1655 * whole alignment or just the current selection with start and end points
1658 * @note if you need references to the actual SequenceI objects in the
1659 * alignment or currently selected then use getSequenceSelection()
1660 * @return selection as new sequenceI objects
1662 public SequenceI[] getSelectionAsNewSequence()
1664 SequenceI[] sequences;
1666 if (selectionGroup == null)
1668 sequences = alignment.getSequencesArray();
1669 AlignmentAnnotation[] annots = alignment.getAlignmentAnnotation();
1670 for (int i = 0; i < sequences.length; i++)
1672 sequences[i] = new Sequence(sequences[i], annots); // construct new
1674 // subset of visible
1680 sequences = selectionGroup.getSelectionAsNewSequences(alignment);
1687 * get the currently selected sequence objects or all the sequences in the
1690 * @return array of references to sequence objects
1692 public SequenceI[] getSequenceSelection()
1694 SequenceI[] sequences = null;
1695 if (selectionGroup != null)
1697 sequences = selectionGroup.getSequencesInOrder(alignment);
1699 if (sequences == null)
1701 sequences = alignment.getSequencesArray();
1707 * This method returns the visible alignment as text, as seen on the GUI, ie
1708 * if columns are hidden they will not be returned in the result. Use this for
1709 * calculating trees, PCA, redundancy etc on views which contain hidden
1714 public jalview.datamodel.CigarArray getViewAsCigars(
1715 boolean selectedRegionOnly)
1717 return new jalview.datamodel.CigarArray(alignment,
1718 (hasHiddenColumns ? colSel : null),
1719 (selectedRegionOnly ? selectionGroup : null));
1723 * return a compact representation of the current alignment selection to pass
1724 * to an analysis function
1726 * @param selectedOnly
1727 * boolean true to just return the selected view
1728 * @return AlignmentView
1730 public jalview.datamodel.AlignmentView getAlignmentView(
1731 boolean selectedOnly)
1733 return getAlignmentView(selectedOnly, false);
1737 * return a compact representation of the current alignment selection to pass
1738 * to an analysis function
1740 * @param selectedOnly
1741 * boolean true to just return the selected view
1743 * boolean true to annotate the alignment view with groups on the
1744 * alignment (and intersecting with selected region if selectedOnly
1746 * @return AlignmentView
1748 public jalview.datamodel.AlignmentView getAlignmentView(
1749 boolean selectedOnly, boolean markGroups)
1751 return new AlignmentView(alignment, colSel, selectionGroup,
1752 hasHiddenColumns, selectedOnly, markGroups);
1756 * This method returns the visible alignment as text, as seen on the GUI, ie
1757 * if columns are hidden they will not be returned in the result. Use this for
1758 * calculating trees, PCA, redundancy etc on views which contain hidden
1763 public String[] getViewAsString(boolean selectedRegionOnly)
1765 String[] selection = null;
1766 SequenceI[] seqs = null;
1768 int start = 0, end = 0;
1769 if (selectedRegionOnly && selectionGroup != null)
1771 iSize = selectionGroup.getSize();
1772 seqs = selectionGroup.getSequencesInOrder(alignment);
1773 start = selectionGroup.getStartRes();
1774 end = selectionGroup.getEndRes() + 1;
1778 iSize = alignment.getHeight();
1779 seqs = alignment.getSequencesArray();
1780 end = alignment.getWidth();
1783 selection = new String[iSize];
1784 if (hasHiddenColumns)
1786 selection = colSel.getVisibleSequenceStrings(start, end, seqs);
1790 for (i = 0; i < iSize; i++)
1792 selection[i] = seqs[i].getSequenceAsString(start, end);
1799 public int[][] getVisibleRegionBoundaries(int min, int max)
1801 Vector regions = new Vector();
1807 if (hasHiddenColumns)
1811 start = colSel.adjustForHiddenColumns(start);
1814 end = colSel.getHiddenBoundaryRight(start);
1825 regions.addElement(new int[]
1828 if (hasHiddenColumns)
1830 start = colSel.adjustForHiddenColumns(end);
1831 start = colSel.getHiddenBoundaryLeft(start) + 1;
1833 } while (end < max);
1835 int[][] startEnd = new int[regions.size()][2];
1837 regions.copyInto(startEnd);
1843 public boolean getShowHiddenMarkers()
1845 return showHiddenMarkers;
1848 public void setShowHiddenMarkers(boolean show)
1850 showHiddenMarkers = show;
1853 public String getSequenceSetId()
1855 if (sequenceSetID == null)
1857 sequenceSetID = alignment.hashCode() + "";
1860 return sequenceSetID;
1864 * unique viewId for synchronizing state with stored Jalview Project
1867 private String viewId = null;
1869 public String getViewId()
1873 viewId = this.getSequenceSetId() + "." + this.hashCode() + "";
1878 public void alignmentChanged(AlignmentPanel ap)
1882 alignment.padGaps();
1884 if (hconsensus != null && autoCalculateConsensus)
1886 updateConservation(ap);
1888 if (autoCalculateConsensus)
1890 updateConsensus(ap);
1892 if (autoCalculateStrucConsensus)
1894 updateStrucConsensus(ap);
1897 // Reset endRes of groups if beyond alignment width
1898 int alWidth = alignment.getWidth();
1899 Vector groups = alignment.getGroups();
1902 for (int i = 0; i < groups.size(); i++)
1904 SequenceGroup sg = (SequenceGroup) groups.elementAt(i);
1905 if (sg.getEndRes() > alWidth)
1907 sg.setEndRes(alWidth - 1);
1912 if (selectionGroup != null && selectionGroup.getEndRes() > alWidth)
1914 selectionGroup.setEndRes(alWidth - 1);
1917 resetAllColourSchemes();
1919 // alignment.adjustSequenceAnnotations();
1922 void resetAllColourSchemes()
1924 ColourSchemeI cs = globalColourScheme;
1927 if (cs instanceof ClustalxColourScheme)
1929 ((ClustalxColourScheme) cs).resetClustalX(alignment.getSequences(),
1930 alignment.getWidth());
1933 cs.setConsensus(hconsensus);
1934 if (cs.conservationApplied())
1936 Alignment al = (Alignment) alignment;
1937 Conservation c = new Conservation("All",
1938 ResidueProperties.propHash, 3, al.getSequences(), 0, al
1941 c.verdict(false, ConsPercGaps);
1943 cs.setConservation(c);
1947 int s, sSize = alignment.getGroups().size();
1948 for (s = 0; s < sSize; s++)
1950 SequenceGroup sg = (SequenceGroup) alignment.getGroups().elementAt(s);
1951 if (sg.cs != null && sg.cs instanceof ClustalxColourScheme)
1953 ((ClustalxColourScheme) sg.cs).resetClustalX(sg
1954 .getSequences(hiddenRepSequences), sg.getWidth());
1956 sg.recalcConservation();
1960 public Color getSequenceColour(SequenceI seq)
1962 if (sequenceColours == null || !sequenceColours.containsKey(seq))
1968 return (Color) sequenceColours.get(seq);
1972 public void setSequenceColour(SequenceI seq, Color col)
1974 if (sequenceColours == null)
1976 sequenceColours = new Hashtable();
1981 sequenceColours.remove(seq);
1985 sequenceColours.put(seq, col);
1990 * returns the visible column regions of the alignment
1992 * @param selectedRegionOnly
1993 * true to just return the contigs intersecting with the selected
1997 public int[] getViewAsVisibleContigs(boolean selectedRegionOnly)
1999 int[] viscontigs = null;
2000 int start = 0, end = 0;
2001 if (selectedRegionOnly && selectionGroup != null)
2003 start = selectionGroup.getStartRes();
2004 end = selectionGroup.getEndRes() + 1;
2008 end = alignment.getWidth();
2010 viscontigs = colSel.getVisibleContigs(start, end);
2015 * get hash of undo and redo list for the alignment
2017 * @return long[] { historyList.hashCode, redoList.hashCode };
2019 public long[] getUndoRedoHash()
2021 if (historyList == null || redoList == null)
2025 { historyList.hashCode(), this.redoList.hashCode() };
2029 * test if a particular set of hashcodes are different to the hashcodes for
2030 * the undo and redo list.
2033 * the stored set of hashcodes as returned by getUndoRedoHash
2034 * @return true if the hashcodes differ (ie the alignment has been edited) or
2035 * the stored hashcode array differs in size
2037 public boolean isUndoRedoHashModified(long[] undoredo)
2039 if (undoredo == null)
2043 long[] cstate = getUndoRedoHash();
2044 if (cstate.length != undoredo.length)
2049 for (int i = 0; i < cstate.length; i++)
2051 if (cstate[i] != undoredo[i])
2059 public boolean getCentreColumnLabels()
2061 return centreColumnLabels;
2064 public void setCentreColumnLabels(boolean centrecolumnlabels)
2066 centreColumnLabels = centrecolumnlabels;
2069 public void updateSequenceIdColours()
2071 Vector groups = alignment.getGroups();
2072 if (sequenceColours == null)
2074 sequenceColours = new Hashtable();
2076 for (int ig = 0, igSize = groups.size(); ig < igSize; ig++)
2078 SequenceGroup sg = (SequenceGroup) groups.elementAt(ig);
2079 if (sg.idColour != null)
2081 Vector sqs = sg.getSequences(hiddenRepSequences);
2082 for (int s = 0, sSize = sqs.size(); s < sSize; s++)
2084 sequenceColours.put(sqs.elementAt(s), sg.idColour);
2091 * enable or disable the display of Database Cross References in the sequence
2094 public void setShowDbRefs(boolean show)
2101 * @return true if Database References are to be displayed on tooltips.
2103 public boolean isShowDbRefs()
2110 * @return true if Non-positional features are to be displayed on tooltips.
2112 public boolean isShowNpFeats()
2118 * enable or disable the display of Non-Positional sequence features in the
2119 * sequence ID tooltip
2123 public void setShowNpFeats(boolean show)
2130 * @return true if view has hidden rows
2132 public boolean hasHiddenRows()
2134 return hasHiddenRows;
2139 * @return true if view has hidden columns
2141 public boolean hasHiddenColumns()
2143 return hasHiddenColumns;
2147 * when set, view will scroll to show the highlighted position
2149 public boolean followHighlight = true;
2152 * @return true if view should scroll to show the highlighted region of a
2156 public boolean getFollowHighlight()
2158 return followHighlight;
2161 public boolean followSelection = true;
2164 * @return true if view selection should always follow the selections
2165 * broadcast by other selection sources
2167 public boolean getFollowSelection()
2169 return followSelection;
2172 private long sgrouphash = -1, colselhash = -1;
2174 boolean showSeqFeaturesHeight;
2177 * checks current SelectionGroup against record of last hash value, and
2181 * update the record of last hash value
2183 * @return true if SelectionGroup changed since last call (when b is true)
2185 boolean isSelectionGroupChanged(boolean b)
2187 int hc = (selectionGroup == null || selectionGroup.getSize() == 0) ? -1
2188 : selectionGroup.hashCode();
2189 if (hc != -1 && hc != sgrouphash)
2201 * checks current colsel against record of last hash value, and optionally
2205 * update the record of last hash value
2206 * @return true if colsel changed since last call (when b is true)
2208 boolean isColSelChanged(boolean b)
2210 int hc = (colSel == null || colSel.size() == 0) ? -1 : colSel
2212 if (hc != -1 && hc != colselhash)
2223 public void sendSelection()
2225 jalview.structure.StructureSelectionManager
2226 .getStructureSelectionManager(Desktop.instance).sendSelection(
2227 new SequenceGroup(getSelectionGroup()),
2228 new ColumnSelection(getColumnSelection()), this);
2231 public void setShowSequenceFeaturesHeight(boolean selected)
2233 showSeqFeaturesHeight = selected;
2236 public boolean getShowSequenceFeaturesHeight()
2238 return showSeqFeaturesHeight;
2241 boolean showUnconserved = false;
2243 public boolean getShowUnconserved()
2245 return showUnconserved;
2248 public void setShowUnconserved(boolean showunconserved)
2250 showUnconserved = showunconserved;
2254 * return the alignPanel containing the given viewport. Use this to get the
2255 * components currently handling the given viewport.
2258 * @return null or an alignPanel guaranteed to have non-null alignFrame
2261 public AlignmentPanel getAlignPanel()
2263 AlignmentPanel[] aps = PaintRefresher.getAssociatedPanels(this
2264 .getSequenceSetId());
2265 AlignmentPanel ap = null;
2266 for (int p = 0; aps != null && p < aps.length; p++)
2268 if (aps[p].av == this)
2276 public boolean getSortByTree()
2281 public void setSortByTree(boolean sort)
2287 * should conservation rows be shown for groups
2289 boolean showGroupConservation = false;
2292 * should consensus rows be shown for groups
2294 boolean showGroupConsensus = false;
2297 * should consensus profile be rendered by default
2299 public boolean showSequenceLogo = false;
2302 * should consensus histograms be rendered by default
2304 public boolean showConsensusHistogram = true;
2307 * @return the showConsensusProfile
2309 public boolean isShowSequenceLogo()
2311 return showSequenceLogo;
2315 * @param showSequenceLogo
2318 public void setShowSequenceLogo(boolean showSequenceLogo)
2320 if (showSequenceLogo != this.showSequenceLogo)
2322 // TODO: decouple settings setting from calculation when refactoring
2323 // annotation update method from alignframe to viewport
2324 this.showSequenceLogo = showSequenceLogo;
2325 if (consensusThread != null)
2327 consensusThread.updateAnnotation();
2329 if (strucConsensusThread != null)
2331 strucConsensusThread.updateAnnotation();
2334 this.showSequenceLogo = showSequenceLogo;
2338 * @param showConsensusHistogram
2339 * the showConsensusHistogram to set
2341 public void setShowConsensusHistogram(boolean showConsensusHistogram)
2343 this.showConsensusHistogram = showConsensusHistogram;
2347 * @return the showGroupConservation
2349 public boolean isShowGroupConservation()
2351 return showGroupConservation;
2355 * @param showGroupConservation
2356 * the showGroupConservation to set
2358 public void setShowGroupConservation(boolean showGroupConservation)
2360 this.showGroupConservation = showGroupConservation;
2364 * @return the showGroupConsensus
2366 public boolean isShowGroupConsensus()
2368 return showGroupConsensus;
2372 * @param showGroupConsensus
2373 * the showGroupConsensus to set
2375 public void setShowGroupConsensus(boolean showGroupConsensus)
2377 this.showGroupConsensus = showGroupConsensus;
2382 * @return flag to indicate if the consensus histogram should be rendered by
2385 public boolean isShowConsensusHistogram()
2387 return this.showConsensusHistogram;
2391 * synthesize a column selection if none exists so it covers the given
2392 * selection group. if wholewidth is false, no column selection is made if the
2393 * selection group covers the whole alignment width.
2398 public void expandColSelection(SequenceGroup sg, boolean wholewidth)
2402 && (sgs = sg.getStartRes()) >= 0
2403 && sg.getStartRes() <= (sge = sg.getEndRes())
2404 && (colSel == null || colSel.getSelected() == null || colSel
2405 .getSelected().size() == 0))
2407 if (!wholewidth && alignment.getWidth() == (1 + sge - sgs))
2414 colSel = new ColumnSelection();
2416 for (int cspos = sg.getStartRes(); cspos <= sg.getEndRes(); cspos++)
2418 colSel.addElement(cspos);
2423 public StructureSelectionManager getStructureSelectionManager()
2425 return StructureSelectionManager
2426 .getStructureSelectionManager(Desktop.instance);
2432 * @return a series of SequenceI arrays, one for each PDBEntry, listing which
2433 * sequence in the alignment holds a reference to it
2435 public SequenceI[][] collateForPDB(PDBEntry[] pdbEntries)
2437 ArrayList<SequenceI[]> seqvectors = new ArrayList<SequenceI[]>();
2438 for (PDBEntry pdb : pdbEntries)
2440 ArrayList<SequenceI> seqs = new ArrayList<SequenceI>();
2441 for (int i = 0; i < alignment.getHeight(); i++)
2443 Vector pdbs = alignment.getSequenceAt(i).getDatasetSequence()
2448 for (int p = 0; p < pdbs.size(); p++)
2450 PDBEntry p1 = (PDBEntry) pdbs.elementAt(p);
2451 if (p1.getId().equals(pdb.getId()))
2453 if (!seqs.contains(sq = alignment.getSequenceAt(i)))
2460 seqvectors.add(seqs.toArray(new SequenceI[seqs.size()]));
2462 return seqvectors.toArray(new SequenceI[seqvectors.size()][]);