2 * Jalview - A Sequence Alignment Editor and Viewer (Development Version 2.4.1)
3 * Copyright (C) 2009 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
20 * Jalview - A Sequence Alignment Editor and Viewer
21 * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
23 * This program is free software; you can redistribute it and/or
24 * modify it under the terms of the GNU General Public License
25 * as published by the Free Software Foundation; either version 2
26 * of the License, or (at your option) any later version.
28 * This program is distributed in the hope that it will be useful,
29 * but WITHOUT ANY WARRANTY; without even the implied warranty of
30 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 * GNU General Public License for more details.
33 * You should have received a copy of the GNU General Public License
34 * along with this program; if not, write to the Free Software
35 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
43 import jalview.analysis.*;
47 import jalview.datamodel.*;
49 import jalview.schemes.*;
50 import jalview.structure.SelectionSource;
51 import jalview.structure.StructureSelectionManager;
59 public class AlignViewport implements SelectionSource
61 private static final int RIGHT_JUSTIFY = 1;
71 boolean showJVSuffix = true;
73 boolean showText = true;
75 boolean showColourText = false;
77 boolean showBoxes = true;
79 boolean wrapAlignment = false;
81 boolean renderGaps = true;
83 boolean showSequenceFeatures = false;
85 boolean showAnnotation = true;
87 boolean colourAppliesToAllGroups = true;
89 ColourSchemeI globalColourScheme = null;
91 boolean conservationColourSelected = false;
93 boolean abovePIDThreshold = false;
95 SequenceGroup selectionGroup;
101 boolean validCharWidth;
107 boolean seqNameItalics;
109 AlignmentI alignment;
111 ColumnSelection colSel = new ColumnSelection();
117 NJTree currentTree = null;
119 boolean scaleAboveWrapped = false;
121 boolean scaleLeftWrapped = true;
123 boolean scaleRightWrapped = true;
125 boolean hasHiddenColumns = false;
127 boolean hasHiddenRows = false;
129 boolean showHiddenMarkers = true;
131 boolean cursorMode = false;
133 // The following vector holds the features which are
134 // currently visible, in the correct order or rendering
135 Hashtable featuresDisplayed = null;
138 public Hashtable[] hconsensus;
140 AlignmentAnnotation consensus;
142 AlignmentAnnotation conservation;
144 AlignmentAnnotation quality;
146 boolean autoCalculateConsensus = true;
149 public int ConsPercGaps = 25; // JBPNote : This should be a scalable property!
151 // JBPNote Prolly only need this in the applet version.
152 private java.beans.PropertyChangeSupport changeSupport = new java.beans.PropertyChangeSupport(
155 boolean ignoreGapsInConsensusCalculation = false;
157 boolean isDataset = false;
159 boolean antiAlias = false;
161 boolean padGaps = false;
163 Rectangle explodedPosition;
167 String sequenceSetID;
169 boolean gatherViewsHere = false;
171 Stack historyList = new Stack();
173 Stack redoList = new Stack();
175 Hashtable sequenceColours;
177 int thresholdTextColour = 0;
179 Color textColour = Color.black;
181 Color textColour2 = Color.white;
183 boolean rightAlignIds = false;
185 Hashtable hiddenRepSequences;
190 * Creates a new AlignViewport object.
192 * @param al alignment to view
194 public AlignViewport(AlignmentI al)
200 * Create a new AlignViewport object with a specific sequence set ID
202 * @param seqsetid (may be null - but potential for ambiguous constructor exception)
204 public AlignViewport(AlignmentI al, String seqsetid)
206 this(al,seqsetid,null);
208 public AlignViewport(AlignmentI al, String seqsetid, String viewid)
210 sequenceSetID = seqsetid;
212 // TODO remove these once 2.4.VAMSAS release finished
213 if (Cache.log!=null && Cache.log.isDebugEnabled() && seqsetid!=null) { Cache.log.debug("Setting viewport's sequence set id : "+sequenceSetID); }
214 if (Cache.log!=null && Cache.log.isDebugEnabled() && viewId!=null) { Cache.log.debug("Setting viewport's view id : "+viewId); }
220 * Create a new AlignViewport with hidden regions
224 * @param hiddenColumns
227 public AlignViewport(AlignmentI al, ColumnSelection hiddenColumns)
230 if (hiddenColumns != null)
232 this.colSel = hiddenColumns;
233 if (hiddenColumns.getHiddenColumns() != null)
235 hasHiddenColumns = true;
241 * New viewport with hidden columns and an existing sequence set id
243 * @param hiddenColumns
244 * @param seqsetid (may be null)
246 public AlignViewport(AlignmentI al, ColumnSelection hiddenColumns, String seqsetid)
248 this(al,hiddenColumns,seqsetid,null);
251 * New viewport with hidden columns and an existing sequence set id and viewid
253 * @param hiddenColumns
254 * @param seqsetid (may be null)
255 * @param viewid (may be null)
257 public AlignViewport(AlignmentI al, ColumnSelection hiddenColumns, String seqsetid, String viewid)
259 sequenceSetID = seqsetid;
261 // TODO remove these once 2.4.VAMSAS release finished
262 if (Cache.log!=null && Cache.log.isDebugEnabled() && seqsetid!=null) { Cache.log.debug("Setting viewport's sequence set id : "+sequenceSetID); }
263 if (Cache.log!=null && Cache.log.isDebugEnabled() && viewId!=null) { Cache.log.debug("Setting viewport's view id : "+viewId); }
265 if (hiddenColumns != null)
267 this.colSel = hiddenColumns;
268 if (hiddenColumns.getHiddenColumns() != null)
270 hasHiddenColumns = true;
279 this.endRes = alignment.getWidth() - 1;
281 this.endSeq = alignment.getHeight() - 1;
283 antiAlias = Cache.getDefault("ANTI_ALIAS", false);
285 showJVSuffix = Cache.getDefault("SHOW_JVSUFFIX", true);
286 showAnnotation = Cache.getDefault("SHOW_ANNOTATIONS", true);
288 rightAlignIds = Cache.getDefault("RIGHT_ALIGN_IDS", false);
289 centreColumnLabels = Cache.getDefault("CENTRE_COLUMN_LABELS", false);
290 autoCalculateConsensus = Cache.getDefault("AUTO_CALC_CONSENSUS", true);
292 padGaps = Cache.getDefault("PAD_GAPS", true);
293 shownpfeats = Cache.getDefault("SHOW_NPFEATS_TOOLTIP",true);
294 showdbrefs = Cache.getDefault("SHOW_DBREFS_TOOLTIP",true);
296 String fontName = Cache.getDefault("FONT_NAME", "SansSerif");
297 String fontStyle = Cache.getDefault("FONT_STYLE", Font.PLAIN + "");
298 String fontSize = Cache.getDefault("FONT_SIZE", "10");
300 seqNameItalics = Cache.getDefault("ID_ITALICS", true);
304 if (fontStyle.equals("bold"))
308 else if (fontStyle.equals("italic"))
313 setFont(new Font(fontName, style, Integer.parseInt(fontSize)));
316 .setGapCharacter(Cache.getDefault("GAP_SYMBOL", "-").charAt(0));
318 // We must set conservation and consensus before setting colour,
319 // as Blosum and Clustal require this to be done
320 if (hconsensus == null && !isDataset)
322 if (!alignment.isNucleotide())
324 conservation = new AlignmentAnnotation("Conservation",
325 "Conservation of total alignment less than " + ConsPercGaps
326 + "% gaps", new Annotation[1], 0f, 11f,
327 AlignmentAnnotation.BAR_GRAPH);
328 conservation.hasText = true;
329 conservation.autoCalculated = true;
331 if (Cache.getDefault("SHOW_CONSERVATION", true))
333 alignment.addAnnotation(conservation);
336 if (Cache.getDefault("SHOW_QUALITY", true))
338 quality = new AlignmentAnnotation("Quality",
339 "Alignment Quality based on Blosum62 scores",
340 new Annotation[1], 0f, 11f, AlignmentAnnotation.BAR_GRAPH);
341 quality.hasText = true;
342 quality.autoCalculated = true;
344 alignment.addAnnotation(quality);
347 // TODO: add menu option action that nulls or creates consensus object depending on if the user wants to see the annotation or not in a specific alignment
348 consensus = new AlignmentAnnotation("Consensus", "PID",
349 new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH);
350 consensus.hasText = true;
351 consensus.autoCalculated = true;
353 if (Cache.getDefault("SHOW_IDENTITY", true))
355 alignment.addAnnotation(consensus);
359 if (jalview.bin.Cache.getProperty("DEFAULT_COLOUR") != null)
361 globalColourScheme = ColourSchemeProperty.getColour(alignment,
362 jalview.bin.Cache.getProperty("DEFAULT_COLOUR"));
364 if (globalColourScheme instanceof UserColourScheme)
366 globalColourScheme = UserDefinedColours.loadDefaultColours();
367 ((UserColourScheme) globalColourScheme).setThreshold(0,
368 getIgnoreGapsConsensus());
371 if (globalColourScheme != null)
373 globalColourScheme.setConsensus(hconsensus);
377 wrapAlignment = jalview.bin.Cache.getDefault("WRAP_ALIGNMENT", false);
378 showUnconserved = jalview.bin.Cache.getDefault("SHOW_UNCONSERVED", false);
379 sortByTree = jalview.bin.Cache.getDefault("SORT_BY_TREE", false);
386 * features are displayed if true
388 public void setShowSequenceFeatures(boolean b)
390 showSequenceFeatures = b;
393 public boolean getShowSequenceFeatures()
395 return showSequenceFeatures;
398 class ConservationThread extends Thread
402 public ConservationThread(AlignmentPanel ap)
411 updatingConservation = true;
413 while (UPDATING_CONSERVATION)
419 ap.paintAlignment(false);
422 } catch (Exception ex)
424 ex.printStackTrace();
428 UPDATING_CONSERVATION = true;
430 int alWidth = alignment.getWidth();
436 Conservation cons = new jalview.analysis.Conservation("All",
437 jalview.schemes.ResidueProperties.propHash, 3, alignment
438 .getSequences(), 0, alWidth - 1);
441 cons.verdict(false, ConsPercGaps);
448 char[] sequence = cons.getConsSequence().getSequence();
460 maxB = 0f - minB; // scalable range for colouring both Conservation and
470 conservation.annotations = new Annotation[alWidth];
474 quality.graphMax = cons.qualityRange[1].floatValue();
475 quality.annotations = new Annotation[alWidth];
476 qmin = cons.qualityRange[0].floatValue();
477 qmax = cons.qualityRange[1].floatValue();
480 for (int i = 0; i < alWidth; i++)
486 if (Character.isDigit(c))
488 value = (int) (c - '0');
499 float vprop = value - min;
501 conservation.annotations[i] = new Annotation(String.valueOf(c),
502 String.valueOf(value), ' ', value, new Color(minR
503 + (maxR * vprop), minG + (maxG * vprop), minB
509 value = ((Double) cons.quality.get(i)).floatValue();
510 vprop = value - qmin;
512 quality.annotations[i] = new Annotation(" ", String
513 .valueOf(value), ' ', value, new Color(minR
514 + (maxR * vprop), minG + (maxG * vprop), minB
518 } catch (OutOfMemoryError error)
520 new OOMWarning("calculating conservation", error);
527 UPDATING_CONSERVATION = false;
528 updatingConservation = false;
532 ap.paintAlignment(true);
538 ConservationThread conservationThread;
540 ConsensusThread consensusThread;
542 boolean consUpdateNeeded = false;
544 static boolean UPDATING_CONSENSUS = false;
546 static boolean UPDATING_CONSERVATION = false;
548 boolean updatingConsensus = false;
550 boolean updatingConservation = false;
553 * centre columnar annotation labels in displayed alignment annotation TODO:
554 * add to jalviewXML and annotation display settings
556 boolean centreColumnLabels = false;
558 private boolean showdbrefs;
560 private boolean shownpfeats;
563 * trigger update of conservation annotation
565 public void updateConservation(final AlignmentPanel ap)
567 // see note in mantis : issue number 8585
568 if (alignment.isNucleotide() || conservation == null || !autoCalculateConsensus)
573 conservationThread = new ConservationThread(ap);
574 conservationThread.start();
578 * trigger update of consensus annotation
580 public void updateConsensus(final AlignmentPanel ap)
582 // see note in mantis : issue number 8585
583 if (consensus == null || !autoCalculateConsensus)
587 consensusThread = new ConsensusThread(ap);
588 consensusThread.start();
591 class ConsensusThread extends Thread
595 public ConsensusThread(AlignmentPanel ap)
602 updatingConsensus = true;
603 while (UPDATING_CONSENSUS)
609 ap.paintAlignment(false);
613 } catch (Exception ex)
615 ex.printStackTrace();
619 UPDATING_CONSENSUS = true;
623 int aWidth = (alignment != null) ? alignment.getWidth() : 0; // null
632 consensus.annotations = null;
633 consensus.annotations = new Annotation[aWidth];
635 hconsensus = new Hashtable[aWidth];
636 AAFrequency.calculate(alignment.getSequencesArray(), 0, alignment
637 .getWidth(), hconsensus);
639 for (int i = 0; i < aWidth; i++)
642 if (ignoreGapsInConsensusCalculation)
644 value = ((Float) hconsensus[i].get(AAFrequency.PID_NOGAPS))
649 value = ((Float) hconsensus[i].get(AAFrequency.PID_GAPS))
653 String maxRes = hconsensus[i].get(AAFrequency.MAXRESIDUE)
655 String mouseOver = hconsensus[i].get(AAFrequency.MAXRESIDUE)
658 if (maxRes.length() > 1)
660 mouseOver = "[" + maxRes + "] ";
664 mouseOver += ((int) value + "%");
665 consensus.annotations[i] = new Annotation(maxRes, mouseOver, ' ',
669 if (globalColourScheme != null)
671 globalColourScheme.setConsensus(hconsensus);
674 } catch (OutOfMemoryError error)
676 alignment.deleteAnnotation(consensus);
680 new OOMWarning("calculating consensus", error);
682 UPDATING_CONSENSUS = false;
683 updatingConsensus = false;
687 ap.paintAlignment(true);
693 * get the consensus sequence as displayed under the PID consensus annotation
696 * @return consensus sequence as a new sequence object
698 public SequenceI getConsensusSeq()
700 if (consensus == null)
702 updateConsensus(null);
704 if (consensus == null)
708 StringBuffer seqs = new StringBuffer();
709 for (int i = 0; i < consensus.annotations.length; i++)
711 if (consensus.annotations[i] != null)
713 if (consensus.annotations[i].description.charAt(0) == '[')
715 seqs.append(consensus.annotations[i].description.charAt(1));
719 seqs.append(consensus.annotations[i].displayCharacter);
724 SequenceI sq = new Sequence("Consensus", seqs.toString());
725 sq.setDescription("Percentage Identity Consensus "
726 + ((ignoreGapsInConsensusCalculation) ? " without gaps" : ""));
733 * @return DOCUMENT ME!
735 public SequenceGroup getSelectionGroup()
737 return selectionGroup;
746 public void setSelectionGroup(SequenceGroup sg)
754 * @return DOCUMENT ME!
756 public boolean getConservationSelected()
758 return conservationColourSelected;
767 public void setConservationSelected(boolean b)
769 conservationColourSelected = b;
775 * @return DOCUMENT ME!
777 public boolean getAbovePIDThreshold()
779 return abovePIDThreshold;
788 public void setAbovePIDThreshold(boolean b)
790 abovePIDThreshold = b;
796 * @return DOCUMENT ME!
798 public int getStartRes()
806 * @return DOCUMENT ME!
808 public int getEndRes()
816 * @return DOCUMENT ME!
818 public int getStartSeq()
829 public void setGlobalColourScheme(ColourSchemeI cs)
831 globalColourScheme = cs;
837 * @return DOCUMENT ME!
839 public ColourSchemeI getGlobalColourScheme()
841 return globalColourScheme;
850 public void setStartRes(int res)
861 public void setStartSeq(int seq)
872 public void setEndRes(int res)
874 if (res > (alignment.getWidth() - 1))
876 // log.System.out.println(" Corrected res from " + res + " to maximum " +
877 // (alignment.getWidth()-1));
878 res = alignment.getWidth() - 1;
895 public void setEndSeq(int seq)
897 if (seq > alignment.getHeight())
899 seq = alignment.getHeight();
913 * @return DOCUMENT ME!
915 public int getEndSeq()
926 public void setFont(Font f)
930 Container c = new Container();
932 java.awt.FontMetrics fm = c.getFontMetrics(font);
933 setCharHeight(fm.getHeight());
934 setCharWidth(fm.charWidth('M'));
935 validCharWidth = true;
941 * @return DOCUMENT ME!
943 public Font getFont()
954 public void setCharWidth(int w)
962 * @return DOCUMENT ME!
964 public int getCharWidth()
975 public void setCharHeight(int h)
983 * @return DOCUMENT ME!
985 public int getCharHeight()
996 public void setWrappedWidth(int w)
998 this.wrappedWidth = w;
1004 * @return DOCUMENT ME!
1006 public int getWrappedWidth()
1008 return wrappedWidth;
1014 * @return DOCUMENT ME!
1016 public AlignmentI getAlignment()
1027 public void setAlignment(AlignmentI align)
1029 if (alignment != null && alignment.getCodonFrames() != null)
1031 StructureSelectionManager.getStructureSelectionManager()
1032 .removeMappings(alignment.getCodonFrames());
1034 this.alignment = align;
1035 if (alignment.getCodonFrames() != null)
1037 StructureSelectionManager.getStructureSelectionManager().addMappings(
1038 alignment.getCodonFrames());
1048 public void setWrapAlignment(boolean state)
1050 wrapAlignment = state;
1059 public void setShowText(boolean state)
1070 public void setRenderGaps(boolean state)
1078 * @return DOCUMENT ME!
1080 public boolean getColourText()
1082 return showColourText;
1091 public void setColourText(boolean state)
1093 showColourText = state;
1102 public void setShowBoxes(boolean state)
1110 * @return DOCUMENT ME!
1112 public boolean getWrapAlignment()
1114 return wrapAlignment;
1120 * @return DOCUMENT ME!
1122 public boolean getShowText()
1130 * @return DOCUMENT ME!
1132 public boolean getShowBoxes()
1140 * @return DOCUMENT ME!
1142 public char getGapCharacter()
1144 return getAlignment().getGapCharacter();
1153 public void setGapCharacter(char gap)
1155 if (getAlignment() != null)
1157 getAlignment().setGapCharacter(gap);
1167 public void setThreshold(int thresh)
1175 * @return DOCUMENT ME!
1177 public int getThreshold()
1188 public void setIncrement(int inc)
1196 * @return DOCUMENT ME!
1198 public int getIncrement()
1206 * @return DOCUMENT ME!
1208 public ColumnSelection getColumnSelection()
1219 public void setCurrentTree(NJTree tree)
1227 * @return DOCUMENT ME!
1229 public NJTree getCurrentTree()
1240 public void setColourAppliesToAllGroups(boolean b)
1242 colourAppliesToAllGroups = b;
1248 * @return DOCUMENT ME!
1250 public boolean getColourAppliesToAllGroups()
1252 return colourAppliesToAllGroups;
1258 * @return DOCUMENT ME!
1260 public boolean getShowJVSuffix()
1262 return showJVSuffix;
1271 public void setShowJVSuffix(boolean b)
1279 * @return DOCUMENT ME!
1281 public boolean getShowAnnotation()
1283 return showAnnotation;
1292 public void setShowAnnotation(boolean b)
1300 * @return DOCUMENT ME!
1302 public boolean getScaleAboveWrapped()
1304 return scaleAboveWrapped;
1310 * @return DOCUMENT ME!
1312 public boolean getScaleLeftWrapped()
1314 return scaleLeftWrapped;
1320 * @return DOCUMENT ME!
1322 public boolean getScaleRightWrapped()
1324 return scaleRightWrapped;
1333 public void setScaleAboveWrapped(boolean b)
1335 scaleAboveWrapped = b;
1344 public void setScaleLeftWrapped(boolean b)
1346 scaleLeftWrapped = b;
1355 public void setScaleRightWrapped(boolean b)
1357 scaleRightWrapped = b;
1361 * Property change listener for changes in alignment
1366 public void addPropertyChangeListener(
1367 java.beans.PropertyChangeListener listener)
1369 changeSupport.addPropertyChangeListener(listener);
1378 public void removePropertyChangeListener(
1379 java.beans.PropertyChangeListener listener)
1381 changeSupport.removePropertyChangeListener(listener);
1385 * Property change listener for changes in alignment
1394 public void firePropertyChange(String prop, Object oldvalue,
1397 changeSupport.firePropertyChange(prop, oldvalue, newvalue);
1400 public void setIgnoreGapsConsensus(boolean b, AlignmentPanel ap)
1402 ignoreGapsInConsensusCalculation = b;
1403 updateConsensus(ap);
1404 if (globalColourScheme != null)
1406 globalColourScheme.setThreshold(globalColourScheme.getThreshold(),
1407 ignoreGapsInConsensusCalculation);
1411 public boolean getIgnoreGapsConsensus()
1413 return ignoreGapsInConsensusCalculation;
1416 public void setDataset(boolean b)
1421 public boolean isDataset()
1426 public void hideSelectedColumns()
1428 if (colSel.size() < 1)
1433 colSel.hideSelectedColumns();
1434 setSelectionGroup(null);
1436 hasHiddenColumns = true;
1439 public void hideColumns(int start, int end)
1443 colSel.hideColumns(start);
1447 colSel.hideColumns(start, end);
1450 hasHiddenColumns = true;
1453 public void hideRepSequences(SequenceI repSequence, SequenceGroup sg)
1455 int sSize = sg.getSize();
1461 if (hiddenRepSequences == null)
1463 hiddenRepSequences = new Hashtable();
1466 hiddenRepSequences.put(repSequence, sg);
1468 // Hide all sequences except the repSequence
1469 SequenceI[] seqs = new SequenceI[sSize - 1];
1471 for (int i = 0; i < sSize; i++)
1473 if (sg.getSequenceAt(i) != repSequence)
1475 if (index == sSize - 1)
1480 seqs[index++] = sg.getSequenceAt(i);
1483 sg.setSeqrep(repSequence);
1484 sg.setHidereps(true);
1489 public void hideAllSelectedSeqs()
1491 if (selectionGroup == null || selectionGroup.getSize() < 1)
1496 SequenceI[] seqs = selectionGroup.getSequencesInOrder(alignment);
1500 setSelectionGroup(null);
1503 public void hideSequence(SequenceI[] seq)
1507 for (int i = 0; i < seq.length; i++)
1509 alignment.getHiddenSequences().hideSequence(seq[i]);
1511 hasHiddenRows = true;
1512 firePropertyChange("alignment", null, alignment.getSequences());
1516 public void showSequence(int index)
1518 Vector tmp = alignment.getHiddenSequences().showSequence(index,
1519 hiddenRepSequences);
1522 if (selectionGroup == null)
1524 selectionGroup = new SequenceGroup();
1525 selectionGroup.setEndRes(alignment.getWidth() - 1);
1528 for (int t = 0; t < tmp.size(); t++)
1530 selectionGroup.addSequence((SequenceI) tmp.elementAt(t), false);
1532 firePropertyChange("alignment", null, alignment.getSequences());
1536 if (alignment.getHiddenSequences().getSize() < 1)
1538 hasHiddenRows = false;
1542 public void showColumn(int col)
1544 colSel.revealHiddenColumns(col);
1545 if (colSel.getHiddenColumns() == null)
1547 hasHiddenColumns = false;
1551 public void showAllHiddenColumns()
1553 colSel.revealAllHiddenColumns();
1554 hasHiddenColumns = false;
1557 public void showAllHiddenSeqs()
1559 if (alignment.getHiddenSequences().getSize() > 0)
1561 if (selectionGroup == null)
1563 selectionGroup = new SequenceGroup();
1564 selectionGroup.setEndRes(alignment.getWidth() - 1);
1566 Vector tmp = alignment.getHiddenSequences().showAll(
1567 hiddenRepSequences);
1568 for (int t = 0; t < tmp.size(); t++)
1570 selectionGroup.addSequence((SequenceI) tmp.elementAt(t), false);
1572 firePropertyChange("alignment", null, alignment.getSequences());
1574 hasHiddenRows = false;
1575 hiddenRepSequences = null;
1579 public void invertColumnSelection()
1581 colSel.invertColumnSelection(0, alignment.getWidth());
1584 public int adjustForHiddenSeqs(int alignmentIndex)
1586 return alignment.getHiddenSequences().adjustForHiddenSeqs(
1591 * This method returns an array of new SequenceI objects derived from the
1592 * whole alignment or just the current selection with start and end points
1595 * @note if you need references to the actual SequenceI objects in the
1596 * alignment or currently selected then use getSequenceSelection()
1597 * @return selection as new sequenceI objects
1599 public SequenceI[] getSelectionAsNewSequence()
1601 SequenceI[] sequences;
1603 if (selectionGroup == null)
1605 sequences = alignment.getSequencesArray();
1606 AlignmentAnnotation[] annots = alignment.getAlignmentAnnotation();
1607 for (int i = 0; i < sequences.length; i++)
1609 sequences[i] = new Sequence(sequences[i], annots); // construct new
1611 // subset of visible
1617 sequences = selectionGroup.getSelectionAsNewSequences(alignment);
1624 * get the currently selected sequence objects or all the sequences in the
1627 * @return array of references to sequence objects
1629 public SequenceI[] getSequenceSelection()
1631 SequenceI[] sequences=null;
1632 if (selectionGroup!=null)
1634 sequences = selectionGroup.getSequencesInOrder(alignment);
1636 if (sequences == null)
1638 sequences = alignment.getSequencesArray();
1644 * This method returns the visible alignment as text, as seen on the GUI, ie
1645 * if columns are hidden they will not be returned in the result. Use this for
1646 * calculating trees, PCA, redundancy etc on views which contain hidden
1651 public jalview.datamodel.CigarArray getViewAsCigars(
1652 boolean selectedRegionOnly)
1654 CigarArray selection = null;
1655 SequenceI[] seqs = null;
1657 int start = 0, end = 0;
1658 if (selectedRegionOnly && selectionGroup != null)
1660 iSize = selectionGroup.getSize();
1661 seqs = selectionGroup.getSequencesInOrder(alignment);
1662 start = selectionGroup.getStartRes();
1663 end = selectionGroup.getEndRes(); // inclusive for start and end in
1664 // SeqCigar constructor
1668 iSize = alignment.getHeight();
1669 seqs = alignment.getSequencesArray();
1670 end = alignment.getWidth() - 1;
1672 SeqCigar[] selseqs = new SeqCigar[iSize];
1673 for (i = 0; i < iSize; i++)
1675 selseqs[i] = new SeqCigar(seqs[i], start, end);
1677 selection = new CigarArray(selseqs);
1678 // now construct the CigarArray operations
1679 if (hasHiddenColumns)
1681 Vector regions = colSel.getHiddenColumns();
1683 int hideStart, hideEnd;
1685 for (int j = 0; last < end & j < regions.size(); j++)
1687 region = (int[]) regions.elementAt(j);
1688 hideStart = region[0];
1689 hideEnd = region[1];
1690 // edit hidden regions to selection range
1691 if (hideStart < last)
1703 if (hideStart > end)
1713 if (hideStart > hideEnd)
1718 * form operations...
1720 if (last < hideStart)
1722 selection.addOperation(CigarArray.M, hideStart - last);
1724 selection.addOperation(CigarArray.D, 1 + hideEnd - hideStart);
1727 // Final match if necessary.
1730 selection.addOperation(CigarArray.M, end - last + 1);
1735 selection.addOperation(CigarArray.M, end - start + 1);
1741 * return a compact representation of the current alignment selection to pass
1742 * to an analysis function
1744 * @param selectedOnly
1745 * boolean true to just return the selected view
1746 * @return AlignmentView
1748 jalview.datamodel.AlignmentView getAlignmentView(boolean selectedOnly)
1751 // this is here because the AlignmentView constructor modifies the
1753 // object. Refactoring of Cigar and alignment view representation should
1754 // be done to remove redundancy.
1755 CigarArray aligview = getViewAsCigars(selectedOnly);
1756 if (aligview != null)
1758 return new AlignmentView(aligview,
1759 (selectedOnly && selectionGroup != null) ? selectionGroup
1760 .getStartRes() : 0);
1766 * This method returns the visible alignment as text, as seen on the GUI, ie
1767 * if columns are hidden they will not be returned in the result. Use this for
1768 * calculating trees, PCA, redundancy etc on views which contain hidden
1773 public String[] getViewAsString(boolean selectedRegionOnly)
1775 String[] selection = null;
1776 SequenceI[] seqs = null;
1778 int start = 0, end = 0;
1779 if (selectedRegionOnly && selectionGroup != null)
1781 iSize = selectionGroup.getSize();
1782 seqs = selectionGroup.getSequencesInOrder(alignment);
1783 start = selectionGroup.getStartRes();
1784 end = selectionGroup.getEndRes() + 1;
1788 iSize = alignment.getHeight();
1789 seqs = alignment.getSequencesArray();
1790 end = alignment.getWidth();
1793 selection = new String[iSize];
1794 if (hasHiddenColumns)
1796 selection = colSel.getVisibleSequenceStrings(start, end, seqs);
1800 for (i = 0; i < iSize; i++)
1802 selection[i] = seqs[i].getSequenceAsString(start, end);
1809 public int[][] getVisibleRegionBoundaries(int min, int max)
1811 Vector regions = new Vector();
1817 if (hasHiddenColumns)
1821 start = colSel.adjustForHiddenColumns(start);
1824 end = colSel.getHiddenBoundaryRight(start);
1835 regions.addElement(new int[]
1838 if (hasHiddenColumns)
1840 start = colSel.adjustForHiddenColumns(end);
1841 start = colSel.getHiddenBoundaryLeft(start) + 1;
1843 } while (end < max);
1845 int[][] startEnd = new int[regions.size()][2];
1847 regions.copyInto(startEnd);
1853 public boolean getShowHiddenMarkers()
1855 return showHiddenMarkers;
1858 public void setShowHiddenMarkers(boolean show)
1860 showHiddenMarkers = show;
1863 public String getSequenceSetId()
1865 if (sequenceSetID == null)
1867 sequenceSetID = alignment.hashCode() + "";
1870 return sequenceSetID;
1873 * unique viewId for synchronizing state with stored Jalview Project
1876 private String viewId=null;
1879 public String getViewId()
1883 viewId = this.getSequenceSetId()+"."+this.hashCode()+"";
1888 public void alignmentChanged(AlignmentPanel ap)
1892 alignment.padGaps();
1894 if (hconsensus != null && autoCalculateConsensus)
1896 updateConservation(ap);
1898 if (autoCalculateConsensus)
1900 updateConsensus(ap);
1903 // Reset endRes of groups if beyond alignment width
1904 int alWidth = alignment.getWidth();
1905 Vector groups = alignment.getGroups();
1908 for (int i = 0; i < groups.size(); i++)
1910 SequenceGroup sg = (SequenceGroup) groups.elementAt(i);
1911 if (sg.getEndRes() > alWidth)
1913 sg.setEndRes(alWidth - 1);
1918 if (selectionGroup != null && selectionGroup.getEndRes() > alWidth)
1920 selectionGroup.setEndRes(alWidth - 1);
1923 resetAllColourSchemes();
1925 // alignment.adjustSequenceAnnotations();
1928 void resetAllColourSchemes()
1930 ColourSchemeI cs = globalColourScheme;
1933 if (cs instanceof ClustalxColourScheme)
1935 ((ClustalxColourScheme) cs).resetClustalX(alignment.getSequences(),
1936 alignment.getWidth());
1939 cs.setConsensus(hconsensus);
1940 if (cs.conservationApplied())
1942 Alignment al = (Alignment) alignment;
1943 Conservation c = new Conservation("All",
1944 ResidueProperties.propHash, 3, al.getSequences(), 0, al
1947 c.verdict(false, ConsPercGaps);
1949 cs.setConservation(c);
1953 int s, sSize = alignment.getGroups().size();
1954 for (s = 0; s < sSize; s++)
1956 SequenceGroup sg = (SequenceGroup) alignment.getGroups().elementAt(s);
1957 if (sg.cs != null && sg.cs instanceof ClustalxColourScheme)
1959 ((ClustalxColourScheme) sg.cs).resetClustalX(sg
1960 .getSequences(hiddenRepSequences), sg.getWidth());
1962 sg.recalcConservation();
1966 public Color getSequenceColour(SequenceI seq)
1968 if (sequenceColours == null || !sequenceColours.containsKey(seq))
1974 return (Color) sequenceColours.get(seq);
1978 public void setSequenceColour(SequenceI seq, Color col)
1980 if (sequenceColours == null)
1982 sequenceColours = new Hashtable();
1987 sequenceColours.remove(seq);
1991 sequenceColours.put(seq, col);
1996 * returns the visible column regions of the alignment
1998 * @param selectedRegionOnly
1999 * true to just return the contigs intersecting with the
2003 public int[] getViewAsVisibleContigs(boolean selectedRegionOnly)
2005 int[] viscontigs = null;
2006 int start = 0, end = 0;
2007 if (selectedRegionOnly && selectionGroup != null)
2009 start = selectionGroup.getStartRes();
2010 end = selectionGroup.getEndRes() + 1;
2014 end = alignment.getWidth();
2016 viscontigs = colSel.getVisibleContigs(start, end);
2021 * get hash of undo and redo list for the alignment
2023 * @return long[] { historyList.hashCode, redoList.hashCode };
2025 public long[] getUndoRedoHash()
2027 if (historyList == null || redoList == null)
2031 { historyList.hashCode(), this.redoList.hashCode() };
2035 * test if a particular set of hashcodes are different to the hashcodes for
2036 * the undo and redo list.
2039 * the stored set of hashcodes as returned by getUndoRedoHash
2040 * @return true if the hashcodes differ (ie the alignment has been edited) or
2041 * the stored hashcode array differs in size
2043 public boolean isUndoRedoHashModified(long[] undoredo)
2045 if (undoredo == null)
2049 long[] cstate = getUndoRedoHash();
2050 if (cstate.length != undoredo.length)
2055 for (int i = 0; i < cstate.length; i++)
2057 if (cstate[i] != undoredo[i])
2065 public boolean getCentreColumnLabels()
2067 return centreColumnLabels;
2070 public void setCentreColumnLabels(boolean centrecolumnlabels)
2072 centreColumnLabels = centrecolumnlabels;
2075 public void updateSequenceIdColours()
2077 Vector groups = alignment.getGroups();
2078 if (sequenceColours == null)
2080 sequenceColours = new Hashtable();
2082 for (int ig = 0, igSize = groups.size(); ig < igSize; ig++)
2084 SequenceGroup sg = (SequenceGroup) groups.elementAt(ig);
2085 if (sg.idColour != null)
2087 Vector sqs = sg.getSequences(hiddenRepSequences);
2088 for (int s = 0, sSize = sqs.size(); s < sSize; s++)
2090 sequenceColours.put(sqs.elementAt(s), sg.idColour);
2097 * enable or disable the display of Database Cross References in the sequence ID tooltip
2099 public void setShowDbRefs(boolean show)
2106 * @return true if Database References are to be displayed on tooltips.
2108 public boolean isShowDbRefs()
2115 * @return true if Non-positional features are to be displayed on tooltips.
2117 public boolean isShowNpFeats()
2122 * enable or disable the display of Non-Positional sequence features in the sequence ID tooltip
2125 public void setShowNpFeats(boolean show)
2131 * @return true if view has hidden rows
2133 public boolean hasHiddenRows()
2135 return hasHiddenRows;
2139 * @return true if view has hidden columns
2141 public boolean hasHiddenColumns()
2143 return hasHiddenColumns;
2146 * when set, view will scroll to show the highlighted position
2148 public boolean followHighlight=true;
2150 * @return true if view should scroll to show the highlighted region of a sequence
2153 public boolean getFollowHighlight() {
2154 return followHighlight;
2156 public boolean followSelection=true;
2158 * @return true if view selection should always follow the selections broadcast by other selection sources
2160 public boolean getFollowSelection() {
2161 return followSelection;
2163 private long sgrouphash=-1,colselhash=-1;
2165 boolean showSeqFeaturesHeight;
2167 * checks current SelectionGroup against record of last hash value, and updates record.
2168 * @return true if SelectionGroup changed since last call
2170 boolean isSelectionGroupChanged() {
2171 int hc=(selectionGroup==null) ? -1 : selectionGroup.hashCode();
2180 * checks current colsel against record of last hash value, and updates record.
2181 * @return true if colsel changed since last call
2183 boolean isColSelChanged() {
2184 int hc=(colSel==null) ? -1 : colSel.hashCode();
2192 public void sendSelection()
2194 jalview.structure.StructureSelectionManager.getStructureSelectionManager().sendSelection(new SequenceGroup(getSelectionGroup()), new ColumnSelection(getColumnSelection()), this);
2196 public void setShowSequenceFeaturesHeight(boolean selected)
2198 showSeqFeaturesHeight = selected;
2200 public boolean getShowSequenceFeaturesHeight()
2202 return showSeqFeaturesHeight;
2204 boolean showUnconserved=false;
2205 public boolean getShowUnconserved()
2207 return showUnconserved;
2209 public void setShowUnconserved(boolean showunconserved)
2211 showUnconserved=showunconserved;
2214 * return the alignPanel containing the given viewport. Use this to get the
2215 * components currently handling the given viewport.
2217 * @return null or an alignPanel guaranteed to have non-null alignFrame reference
2219 public AlignmentPanel getAlignPanel()
2221 AlignmentPanel[] aps = PaintRefresher.getAssociatedPanels(this.getSequenceSetId());
2222 AlignmentPanel ap=null;
2223 for (int p=0;aps!=null && p<aps.length; p++)
2225 if (aps[p].av == this)
2232 public boolean getSortByTree()
2236 public void setSortByTree(boolean sort) {