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;
145 AlignmentAnnotation[] groupConsensus;
146 AlignmentAnnotation[] groupConservation;
148 boolean autoCalculateConsensus = true;
151 public int ConsPercGaps = 25; // JBPNote : This should be a scalable property!
153 // JBPNote Prolly only need this in the applet version.
154 private java.beans.PropertyChangeSupport changeSupport = new java.beans.PropertyChangeSupport(
157 boolean ignoreGapsInConsensusCalculation = false;
159 boolean isDataset = false;
161 boolean antiAlias = false;
163 boolean padGaps = false;
165 Rectangle explodedPosition;
169 String sequenceSetID;
171 boolean gatherViewsHere = false;
173 Stack historyList = new Stack();
175 Stack redoList = new Stack();
177 Hashtable sequenceColours;
179 int thresholdTextColour = 0;
181 Color textColour = Color.black;
183 Color textColour2 = Color.white;
185 boolean rightAlignIds = false;
187 Hashtable hiddenRepSequences;
192 * Creates a new AlignViewport object.
194 * @param al alignment to view
196 public AlignViewport(AlignmentI al)
202 * Create a new AlignViewport object with a specific sequence set ID
204 * @param seqsetid (may be null - but potential for ambiguous constructor exception)
206 public AlignViewport(AlignmentI al, String seqsetid)
208 this(al,seqsetid,null);
210 public AlignViewport(AlignmentI al, String seqsetid, String viewid)
212 sequenceSetID = seqsetid;
214 // TODO remove these once 2.4.VAMSAS release finished
215 if (Cache.log!=null && Cache.log.isDebugEnabled() && seqsetid!=null) { Cache.log.debug("Setting viewport's sequence set id : "+sequenceSetID); }
216 if (Cache.log!=null && Cache.log.isDebugEnabled() && viewId!=null) { Cache.log.debug("Setting viewport's view id : "+viewId); }
222 * Create a new AlignViewport with hidden regions
226 * @param hiddenColumns
229 public AlignViewport(AlignmentI al, ColumnSelection hiddenColumns)
232 if (hiddenColumns != null)
234 this.colSel = hiddenColumns;
235 if (hiddenColumns.getHiddenColumns() != null)
237 hasHiddenColumns = true;
243 * New viewport with hidden columns and an existing sequence set id
245 * @param hiddenColumns
246 * @param seqsetid (may be null)
248 public AlignViewport(AlignmentI al, ColumnSelection hiddenColumns, String seqsetid)
250 this(al,hiddenColumns,seqsetid,null);
253 * New viewport with hidden columns and an existing sequence set id and viewid
255 * @param hiddenColumns
256 * @param seqsetid (may be null)
257 * @param viewid (may be null)
259 public AlignViewport(AlignmentI al, ColumnSelection hiddenColumns, String seqsetid, String viewid)
261 sequenceSetID = seqsetid;
263 // TODO remove these once 2.4.VAMSAS release finished
264 if (Cache.log!=null && Cache.log.isDebugEnabled() && seqsetid!=null) { Cache.log.debug("Setting viewport's sequence set id : "+sequenceSetID); }
265 if (Cache.log!=null && Cache.log.isDebugEnabled() && viewId!=null) { Cache.log.debug("Setting viewport's view id : "+viewId); }
267 if (hiddenColumns != null)
269 this.colSel = hiddenColumns;
270 if (hiddenColumns.getHiddenColumns() != null)
272 hasHiddenColumns = true;
281 this.endRes = alignment.getWidth() - 1;
283 this.endSeq = alignment.getHeight() - 1;
285 antiAlias = Cache.getDefault("ANTI_ALIAS", false);
287 showJVSuffix = Cache.getDefault("SHOW_JVSUFFIX", true);
288 showAnnotation = Cache.getDefault("SHOW_ANNOTATIONS", true);
290 rightAlignIds = Cache.getDefault("RIGHT_ALIGN_IDS", false);
291 centreColumnLabels = Cache.getDefault("CENTRE_COLUMN_LABELS", false);
292 autoCalculateConsensus = Cache.getDefault("AUTO_CALC_CONSENSUS", true);
294 padGaps = Cache.getDefault("PAD_GAPS", true);
295 shownpfeats = Cache.getDefault("SHOW_NPFEATS_TOOLTIP",true);
296 showdbrefs = Cache.getDefault("SHOW_DBREFS_TOOLTIP",true);
298 String fontName = Cache.getDefault("FONT_NAME", "SansSerif");
299 String fontStyle = Cache.getDefault("FONT_STYLE", Font.PLAIN + "");
300 String fontSize = Cache.getDefault("FONT_SIZE", "10");
302 seqNameItalics = Cache.getDefault("ID_ITALICS", true);
306 if (fontStyle.equals("bold"))
310 else if (fontStyle.equals("italic"))
315 setFont(new Font(fontName, style, Integer.parseInt(fontSize)));
318 .setGapCharacter(Cache.getDefault("GAP_SYMBOL", "-").charAt(0));
320 // We must set conservation and consensus before setting colour,
321 // as Blosum and Clustal require this to be done
322 if (hconsensus == null && !isDataset)
324 if (!alignment.isNucleotide())
326 conservation = new AlignmentAnnotation("Conservation",
327 "Conservation of total alignment less than " + ConsPercGaps
328 + "% gaps", new Annotation[1], 0f, 11f,
329 AlignmentAnnotation.BAR_GRAPH);
330 conservation.hasText = true;
331 conservation.autoCalculated = true;
333 if (Cache.getDefault("SHOW_CONSERVATION", true))
335 alignment.addAnnotation(conservation);
338 if (Cache.getDefault("SHOW_QUALITY", true))
340 quality = new AlignmentAnnotation("Quality",
341 "Alignment Quality based on Blosum62 scores",
342 new Annotation[1], 0f, 11f, AlignmentAnnotation.BAR_GRAPH);
343 quality.hasText = true;
344 quality.autoCalculated = true;
346 alignment.addAnnotation(quality);
349 // 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
350 consensus = new AlignmentAnnotation("Consensus", "PID",
351 new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH);
352 consensus.hasText = true;
353 consensus.autoCalculated = true;
355 if (Cache.getDefault("SHOW_IDENTITY", true))
357 alignment.addAnnotation(consensus);
361 if (jalview.bin.Cache.getProperty("DEFAULT_COLOUR") != null)
363 globalColourScheme = ColourSchemeProperty.getColour(alignment,
364 jalview.bin.Cache.getProperty("DEFAULT_COLOUR"));
366 if (globalColourScheme instanceof UserColourScheme)
368 globalColourScheme = UserDefinedColours.loadDefaultColours();
369 ((UserColourScheme) globalColourScheme).setThreshold(0,
370 getIgnoreGapsConsensus());
373 if (globalColourScheme != null)
375 globalColourScheme.setConsensus(hconsensus);
379 wrapAlignment = jalview.bin.Cache.getDefault("WRAP_ALIGNMENT", false);
380 showUnconserved = jalview.bin.Cache.getDefault("SHOW_UNCONSERVED", false);
381 sortByTree = jalview.bin.Cache.getDefault("SORT_BY_TREE", false);
388 * features are displayed if true
390 public void setShowSequenceFeatures(boolean b)
392 showSequenceFeatures = b;
395 public boolean getShowSequenceFeatures()
397 return showSequenceFeatures;
400 ConservationThread conservationThread;
402 ConsensusThread consensusThread;
404 boolean consUpdateNeeded = false;
406 static boolean UPDATING_CONSENSUS = false;
408 static boolean UPDATING_CONSERVATION = false;
410 boolean updatingConsensus = false;
412 boolean updatingConservation = false;
415 * centre columnar annotation labels in displayed alignment annotation TODO:
416 * add to jalviewXML and annotation display settings
418 boolean centreColumnLabels = false;
420 private boolean showdbrefs;
422 private boolean shownpfeats;
425 * trigger update of conservation annotation
427 public void updateConservation(final AlignmentPanel ap)
429 // see note in mantis : issue number 8585
430 if (alignment.isNucleotide() || conservation == null || !autoCalculateConsensus)
435 conservationThread = new ConservationThread(this, ap);
436 conservationThread.start();
440 * trigger update of consensus annotation
442 public void updateConsensus(final AlignmentPanel ap)
444 // see note in mantis : issue number 8585
445 if (consensus == null || !autoCalculateConsensus)
449 consensusThread = new ConsensusThread(ap);
450 consensusThread.start();
453 class ConsensusThread extends Thread
457 public ConsensusThread(AlignmentPanel ap)
464 updatingConsensus = true;
465 while (UPDATING_CONSENSUS)
471 ap.paintAlignment(false);
475 } catch (Exception ex)
477 ex.printStackTrace();
481 UPDATING_CONSENSUS = true;
485 int aWidth = (alignment != null) ? alignment.getWidth() : 0; // null
494 consensus.annotations = null;
495 consensus.annotations = new Annotation[aWidth];
497 hconsensus = new Hashtable[aWidth];
498 AAFrequency.calculate(alignment.getSequencesArray(), 0, alignment
499 .getWidth(), hconsensus);
500 AAFrequency.completeConsensus(consensus,hconsensus,0,aWidth,ignoreGapsInConsensusCalculation);
502 if (globalColourScheme != null)
504 globalColourScheme.setConsensus(hconsensus);
507 } catch (OutOfMemoryError error)
509 alignment.deleteAnnotation(consensus);
513 new OOMWarning("calculating consensus", error);
515 UPDATING_CONSENSUS = false;
516 updatingConsensus = false;
520 ap.paintAlignment(true);
526 * get the consensus sequence as displayed under the PID consensus annotation
529 * @return consensus sequence as a new sequence object
531 public SequenceI getConsensusSeq()
533 if (consensus == null)
535 updateConsensus(null);
537 if (consensus == null)
541 StringBuffer seqs = new StringBuffer();
542 for (int i = 0; i < consensus.annotations.length; i++)
544 if (consensus.annotations[i] != null)
546 if (consensus.annotations[i].description.charAt(0) == '[')
548 seqs.append(consensus.annotations[i].description.charAt(1));
552 seqs.append(consensus.annotations[i].displayCharacter);
557 SequenceI sq = new Sequence("Consensus", seqs.toString());
558 sq.setDescription("Percentage Identity Consensus "
559 + ((ignoreGapsInConsensusCalculation) ? " without gaps" : ""));
566 * @return DOCUMENT ME!
568 public SequenceGroup getSelectionGroup()
570 return selectionGroup;
579 public void setSelectionGroup(SequenceGroup sg)
587 * @return DOCUMENT ME!
589 public boolean getConservationSelected()
591 return conservationColourSelected;
600 public void setConservationSelected(boolean b)
602 conservationColourSelected = b;
608 * @return DOCUMENT ME!
610 public boolean getAbovePIDThreshold()
612 return abovePIDThreshold;
621 public void setAbovePIDThreshold(boolean b)
623 abovePIDThreshold = b;
629 * @return DOCUMENT ME!
631 public int getStartRes()
639 * @return DOCUMENT ME!
641 public int getEndRes()
649 * @return DOCUMENT ME!
651 public int getStartSeq()
662 public void setGlobalColourScheme(ColourSchemeI cs)
664 globalColourScheme = cs;
670 * @return DOCUMENT ME!
672 public ColourSchemeI getGlobalColourScheme()
674 return globalColourScheme;
683 public void setStartRes(int res)
694 public void setStartSeq(int seq)
705 public void setEndRes(int res)
707 if (res > (alignment.getWidth() - 1))
709 // log.System.out.println(" Corrected res from " + res + " to maximum " +
710 // (alignment.getWidth()-1));
711 res = alignment.getWidth() - 1;
728 public void setEndSeq(int seq)
730 if (seq > alignment.getHeight())
732 seq = alignment.getHeight();
746 * @return DOCUMENT ME!
748 public int getEndSeq()
759 public void setFont(Font f)
763 Container c = new Container();
765 java.awt.FontMetrics fm = c.getFontMetrics(font);
766 setCharHeight(fm.getHeight());
767 setCharWidth(fm.charWidth('M'));
768 validCharWidth = true;
774 * @return DOCUMENT ME!
776 public Font getFont()
787 public void setCharWidth(int w)
795 * @return DOCUMENT ME!
797 public int getCharWidth()
808 public void setCharHeight(int h)
816 * @return DOCUMENT ME!
818 public int getCharHeight()
829 public void setWrappedWidth(int w)
831 this.wrappedWidth = w;
837 * @return DOCUMENT ME!
839 public int getWrappedWidth()
847 * @return DOCUMENT ME!
849 public AlignmentI getAlignment()
860 public void setAlignment(AlignmentI align)
862 if (alignment != null && alignment.getCodonFrames() != null)
864 StructureSelectionManager.getStructureSelectionManager()
865 .removeMappings(alignment.getCodonFrames());
867 this.alignment = align;
868 if (alignment.getCodonFrames() != null)
870 StructureSelectionManager.getStructureSelectionManager().addMappings(
871 alignment.getCodonFrames());
881 public void setWrapAlignment(boolean state)
883 wrapAlignment = state;
892 public void setShowText(boolean state)
903 public void setRenderGaps(boolean state)
911 * @return DOCUMENT ME!
913 public boolean getColourText()
915 return showColourText;
924 public void setColourText(boolean state)
926 showColourText = state;
935 public void setShowBoxes(boolean state)
943 * @return DOCUMENT ME!
945 public boolean getWrapAlignment()
947 return wrapAlignment;
953 * @return DOCUMENT ME!
955 public boolean getShowText()
963 * @return DOCUMENT ME!
965 public boolean getShowBoxes()
973 * @return DOCUMENT ME!
975 public char getGapCharacter()
977 return getAlignment().getGapCharacter();
986 public void setGapCharacter(char gap)
988 if (getAlignment() != null)
990 getAlignment().setGapCharacter(gap);
1000 public void setThreshold(int thresh)
1008 * @return DOCUMENT ME!
1010 public int getThreshold()
1021 public void setIncrement(int inc)
1029 * @return DOCUMENT ME!
1031 public int getIncrement()
1039 * @return DOCUMENT ME!
1041 public ColumnSelection getColumnSelection()
1052 public void setCurrentTree(NJTree tree)
1060 * @return DOCUMENT ME!
1062 public NJTree getCurrentTree()
1073 public void setColourAppliesToAllGroups(boolean b)
1075 colourAppliesToAllGroups = b;
1081 * @return DOCUMENT ME!
1083 public boolean getColourAppliesToAllGroups()
1085 return colourAppliesToAllGroups;
1091 * @return DOCUMENT ME!
1093 public boolean getShowJVSuffix()
1095 return showJVSuffix;
1104 public void setShowJVSuffix(boolean b)
1112 * @return DOCUMENT ME!
1114 public boolean getShowAnnotation()
1116 return showAnnotation;
1125 public void setShowAnnotation(boolean b)
1133 * @return DOCUMENT ME!
1135 public boolean getScaleAboveWrapped()
1137 return scaleAboveWrapped;
1143 * @return DOCUMENT ME!
1145 public boolean getScaleLeftWrapped()
1147 return scaleLeftWrapped;
1153 * @return DOCUMENT ME!
1155 public boolean getScaleRightWrapped()
1157 return scaleRightWrapped;
1166 public void setScaleAboveWrapped(boolean b)
1168 scaleAboveWrapped = b;
1177 public void setScaleLeftWrapped(boolean b)
1179 scaleLeftWrapped = b;
1188 public void setScaleRightWrapped(boolean b)
1190 scaleRightWrapped = b;
1194 * Property change listener for changes in alignment
1199 public void addPropertyChangeListener(
1200 java.beans.PropertyChangeListener listener)
1202 changeSupport.addPropertyChangeListener(listener);
1211 public void removePropertyChangeListener(
1212 java.beans.PropertyChangeListener listener)
1214 changeSupport.removePropertyChangeListener(listener);
1218 * Property change listener for changes in alignment
1227 public void firePropertyChange(String prop, Object oldvalue,
1230 changeSupport.firePropertyChange(prop, oldvalue, newvalue);
1233 public void setIgnoreGapsConsensus(boolean b, AlignmentPanel ap)
1235 ignoreGapsInConsensusCalculation = b;
1236 updateConsensus(ap);
1237 if (globalColourScheme != null)
1239 globalColourScheme.setThreshold(globalColourScheme.getThreshold(),
1240 ignoreGapsInConsensusCalculation);
1244 public boolean getIgnoreGapsConsensus()
1246 return ignoreGapsInConsensusCalculation;
1249 public void setDataset(boolean b)
1254 public boolean isDataset()
1259 public void hideSelectedColumns()
1261 if (colSel.size() < 1)
1266 colSel.hideSelectedColumns();
1267 setSelectionGroup(null);
1269 hasHiddenColumns = true;
1272 public void hideColumns(int start, int end)
1276 colSel.hideColumns(start);
1280 colSel.hideColumns(start, end);
1283 hasHiddenColumns = true;
1286 public void hideRepSequences(SequenceI repSequence, SequenceGroup sg)
1288 int sSize = sg.getSize();
1294 if (hiddenRepSequences == null)
1296 hiddenRepSequences = new Hashtable();
1299 hiddenRepSequences.put(repSequence, sg);
1301 // Hide all sequences except the repSequence
1302 SequenceI[] seqs = new SequenceI[sSize - 1];
1304 for (int i = 0; i < sSize; i++)
1306 if (sg.getSequenceAt(i) != repSequence)
1308 if (index == sSize - 1)
1313 seqs[index++] = sg.getSequenceAt(i);
1316 sg.setSeqrep(repSequence);
1317 sg.setHidereps(true);
1322 public void hideAllSelectedSeqs()
1324 if (selectionGroup == null || selectionGroup.getSize() < 1)
1329 SequenceI[] seqs = selectionGroup.getSequencesInOrder(alignment);
1333 setSelectionGroup(null);
1336 public void hideSequence(SequenceI[] seq)
1340 for (int i = 0; i < seq.length; i++)
1342 alignment.getHiddenSequences().hideSequence(seq[i]);
1344 hasHiddenRows = true;
1345 firePropertyChange("alignment", null, alignment.getSequences());
1349 public void showSequence(int index)
1351 Vector tmp = alignment.getHiddenSequences().showSequence(index,
1352 hiddenRepSequences);
1355 if (selectionGroup == null)
1357 selectionGroup = new SequenceGroup();
1358 selectionGroup.setEndRes(alignment.getWidth() - 1);
1361 for (int t = 0; t < tmp.size(); t++)
1363 selectionGroup.addSequence((SequenceI) tmp.elementAt(t), false);
1365 firePropertyChange("alignment", null, alignment.getSequences());
1369 if (alignment.getHiddenSequences().getSize() < 1)
1371 hasHiddenRows = false;
1375 public void showColumn(int col)
1377 colSel.revealHiddenColumns(col);
1378 if (colSel.getHiddenColumns() == null)
1380 hasHiddenColumns = false;
1384 public void showAllHiddenColumns()
1386 colSel.revealAllHiddenColumns();
1387 hasHiddenColumns = false;
1390 public void showAllHiddenSeqs()
1392 if (alignment.getHiddenSequences().getSize() > 0)
1394 if (selectionGroup == null)
1396 selectionGroup = new SequenceGroup();
1397 selectionGroup.setEndRes(alignment.getWidth() - 1);
1399 Vector tmp = alignment.getHiddenSequences().showAll(
1400 hiddenRepSequences);
1401 for (int t = 0; t < tmp.size(); t++)
1403 selectionGroup.addSequence((SequenceI) tmp.elementAt(t), false);
1405 firePropertyChange("alignment", null, alignment.getSequences());
1407 hasHiddenRows = false;
1408 hiddenRepSequences = null;
1412 public void invertColumnSelection()
1414 colSel.invertColumnSelection(0, alignment.getWidth());
1417 public int adjustForHiddenSeqs(int alignmentIndex)
1419 return alignment.getHiddenSequences().adjustForHiddenSeqs(
1424 * This method returns an array of new SequenceI objects derived from the
1425 * whole alignment or just the current selection with start and end points
1428 * @note if you need references to the actual SequenceI objects in the
1429 * alignment or currently selected then use getSequenceSelection()
1430 * @return selection as new sequenceI objects
1432 public SequenceI[] getSelectionAsNewSequence()
1434 SequenceI[] sequences;
1436 if (selectionGroup == null)
1438 sequences = alignment.getSequencesArray();
1439 AlignmentAnnotation[] annots = alignment.getAlignmentAnnotation();
1440 for (int i = 0; i < sequences.length; i++)
1442 sequences[i] = new Sequence(sequences[i], annots); // construct new
1444 // subset of visible
1450 sequences = selectionGroup.getSelectionAsNewSequences(alignment);
1457 * get the currently selected sequence objects or all the sequences in the
1460 * @return array of references to sequence objects
1462 public SequenceI[] getSequenceSelection()
1464 SequenceI[] sequences=null;
1465 if (selectionGroup!=null)
1467 sequences = selectionGroup.getSequencesInOrder(alignment);
1469 if (sequences == null)
1471 sequences = alignment.getSequencesArray();
1477 * This method returns the visible alignment as text, as seen on the GUI, ie
1478 * if columns are hidden they will not be returned in the result. Use this for
1479 * calculating trees, PCA, redundancy etc on views which contain hidden
1484 public jalview.datamodel.CigarArray getViewAsCigars(
1485 boolean selectedRegionOnly)
1487 CigarArray selection = null;
1488 SequenceI[] seqs = null;
1490 int start = 0, end = 0;
1491 if (selectedRegionOnly && selectionGroup != null)
1493 iSize = selectionGroup.getSize();
1494 seqs = selectionGroup.getSequencesInOrder(alignment);
1495 start = selectionGroup.getStartRes();
1496 end = selectionGroup.getEndRes(); // inclusive for start and end in
1497 // SeqCigar constructor
1501 iSize = alignment.getHeight();
1502 seqs = alignment.getSequencesArray();
1503 end = alignment.getWidth() - 1;
1505 SeqCigar[] selseqs = new SeqCigar[iSize];
1506 for (i = 0; i < iSize; i++)
1508 selseqs[i] = new SeqCigar(seqs[i], start, end);
1510 selection = new CigarArray(selseqs);
1511 // now construct the CigarArray operations
1512 if (hasHiddenColumns)
1514 Vector regions = colSel.getHiddenColumns();
1516 int hideStart, hideEnd;
1518 for (int j = 0; last < end & j < regions.size(); j++)
1520 region = (int[]) regions.elementAt(j);
1521 hideStart = region[0];
1522 hideEnd = region[1];
1523 // edit hidden regions to selection range
1524 if (hideStart < last)
1536 if (hideStart > end)
1546 if (hideStart > hideEnd)
1551 * form operations...
1553 if (last < hideStart)
1555 selection.addOperation(CigarArray.M, hideStart - last);
1557 selection.addOperation(CigarArray.D, 1 + hideEnd - hideStart);
1560 // Final match if necessary.
1563 selection.addOperation(CigarArray.M, end - last + 1);
1568 selection.addOperation(CigarArray.M, end - start + 1);
1574 * return a compact representation of the current alignment selection to pass
1575 * to an analysis function
1577 * @param selectedOnly
1578 * boolean true to just return the selected view
1579 * @return AlignmentView
1581 jalview.datamodel.AlignmentView getAlignmentView(boolean selectedOnly)
1584 // this is here because the AlignmentView constructor modifies the
1586 // object. Refactoring of Cigar and alignment view representation should
1587 // be done to remove redundancy.
1588 CigarArray aligview = getViewAsCigars(selectedOnly);
1589 if (aligview != null)
1591 return new AlignmentView(aligview,
1592 (selectedOnly && selectionGroup != null) ? selectionGroup
1593 .getStartRes() : 0);
1599 * This method returns the visible alignment as text, as seen on the GUI, ie
1600 * if columns are hidden they will not be returned in the result. Use this for
1601 * calculating trees, PCA, redundancy etc on views which contain hidden
1606 public String[] getViewAsString(boolean selectedRegionOnly)
1608 String[] selection = null;
1609 SequenceI[] seqs = null;
1611 int start = 0, end = 0;
1612 if (selectedRegionOnly && selectionGroup != null)
1614 iSize = selectionGroup.getSize();
1615 seqs = selectionGroup.getSequencesInOrder(alignment);
1616 start = selectionGroup.getStartRes();
1617 end = selectionGroup.getEndRes() + 1;
1621 iSize = alignment.getHeight();
1622 seqs = alignment.getSequencesArray();
1623 end = alignment.getWidth();
1626 selection = new String[iSize];
1627 if (hasHiddenColumns)
1629 selection = colSel.getVisibleSequenceStrings(start, end, seqs);
1633 for (i = 0; i < iSize; i++)
1635 selection[i] = seqs[i].getSequenceAsString(start, end);
1642 public int[][] getVisibleRegionBoundaries(int min, int max)
1644 Vector regions = new Vector();
1650 if (hasHiddenColumns)
1654 start = colSel.adjustForHiddenColumns(start);
1657 end = colSel.getHiddenBoundaryRight(start);
1668 regions.addElement(new int[]
1671 if (hasHiddenColumns)
1673 start = colSel.adjustForHiddenColumns(end);
1674 start = colSel.getHiddenBoundaryLeft(start) + 1;
1676 } while (end < max);
1678 int[][] startEnd = new int[regions.size()][2];
1680 regions.copyInto(startEnd);
1686 public boolean getShowHiddenMarkers()
1688 return showHiddenMarkers;
1691 public void setShowHiddenMarkers(boolean show)
1693 showHiddenMarkers = show;
1696 public String getSequenceSetId()
1698 if (sequenceSetID == null)
1700 sequenceSetID = alignment.hashCode() + "";
1703 return sequenceSetID;
1706 * unique viewId for synchronizing state with stored Jalview Project
1709 private String viewId=null;
1712 public String getViewId()
1716 viewId = this.getSequenceSetId()+"."+this.hashCode()+"";
1721 public void alignmentChanged(AlignmentPanel ap)
1725 alignment.padGaps();
1727 if (hconsensus != null && autoCalculateConsensus)
1729 updateConservation(ap);
1731 if (autoCalculateConsensus)
1733 updateConsensus(ap);
1736 // Reset endRes of groups if beyond alignment width
1737 int alWidth = alignment.getWidth();
1738 Vector groups = alignment.getGroups();
1741 for (int i = 0; i < groups.size(); i++)
1743 SequenceGroup sg = (SequenceGroup) groups.elementAt(i);
1744 if (sg.getEndRes() > alWidth)
1746 sg.setEndRes(alWidth - 1);
1751 if (selectionGroup != null && selectionGroup.getEndRes() > alWidth)
1753 selectionGroup.setEndRes(alWidth - 1);
1756 resetAllColourSchemes();
1758 // alignment.adjustSequenceAnnotations();
1761 void resetAllColourSchemes()
1763 ColourSchemeI cs = globalColourScheme;
1766 if (cs instanceof ClustalxColourScheme)
1768 ((ClustalxColourScheme) cs).resetClustalX(alignment.getSequences(),
1769 alignment.getWidth());
1772 cs.setConsensus(hconsensus);
1773 if (cs.conservationApplied())
1775 Alignment al = (Alignment) alignment;
1776 Conservation c = new Conservation("All",
1777 ResidueProperties.propHash, 3, al.getSequences(), 0, al
1780 c.verdict(false, ConsPercGaps);
1782 cs.setConservation(c);
1786 int s, sSize = alignment.getGroups().size();
1787 for (s = 0; s < sSize; s++)
1789 SequenceGroup sg = (SequenceGroup) alignment.getGroups().elementAt(s);
1790 if (sg.cs != null && sg.cs instanceof ClustalxColourScheme)
1792 ((ClustalxColourScheme) sg.cs).resetClustalX(sg
1793 .getSequences(hiddenRepSequences), sg.getWidth());
1795 sg.recalcConservation();
1799 public Color getSequenceColour(SequenceI seq)
1801 if (sequenceColours == null || !sequenceColours.containsKey(seq))
1807 return (Color) sequenceColours.get(seq);
1811 public void setSequenceColour(SequenceI seq, Color col)
1813 if (sequenceColours == null)
1815 sequenceColours = new Hashtable();
1820 sequenceColours.remove(seq);
1824 sequenceColours.put(seq, col);
1829 * returns the visible column regions of the alignment
1831 * @param selectedRegionOnly
1832 * true to just return the contigs intersecting with the
1836 public int[] getViewAsVisibleContigs(boolean selectedRegionOnly)
1838 int[] viscontigs = null;
1839 int start = 0, end = 0;
1840 if (selectedRegionOnly && selectionGroup != null)
1842 start = selectionGroup.getStartRes();
1843 end = selectionGroup.getEndRes() + 1;
1847 end = alignment.getWidth();
1849 viscontigs = colSel.getVisibleContigs(start, end);
1854 * get hash of undo and redo list for the alignment
1856 * @return long[] { historyList.hashCode, redoList.hashCode };
1858 public long[] getUndoRedoHash()
1860 if (historyList == null || redoList == null)
1864 { historyList.hashCode(), this.redoList.hashCode() };
1868 * test if a particular set of hashcodes are different to the hashcodes for
1869 * the undo and redo list.
1872 * the stored set of hashcodes as returned by getUndoRedoHash
1873 * @return true if the hashcodes differ (ie the alignment has been edited) or
1874 * the stored hashcode array differs in size
1876 public boolean isUndoRedoHashModified(long[] undoredo)
1878 if (undoredo == null)
1882 long[] cstate = getUndoRedoHash();
1883 if (cstate.length != undoredo.length)
1888 for (int i = 0; i < cstate.length; i++)
1890 if (cstate[i] != undoredo[i])
1898 public boolean getCentreColumnLabels()
1900 return centreColumnLabels;
1903 public void setCentreColumnLabels(boolean centrecolumnlabels)
1905 centreColumnLabels = centrecolumnlabels;
1908 public void updateSequenceIdColours()
1910 Vector groups = alignment.getGroups();
1911 if (sequenceColours == null)
1913 sequenceColours = new Hashtable();
1915 for (int ig = 0, igSize = groups.size(); ig < igSize; ig++)
1917 SequenceGroup sg = (SequenceGroup) groups.elementAt(ig);
1918 if (sg.idColour != null)
1920 Vector sqs = sg.getSequences(hiddenRepSequences);
1921 for (int s = 0, sSize = sqs.size(); s < sSize; s++)
1923 sequenceColours.put(sqs.elementAt(s), sg.idColour);
1930 * enable or disable the display of Database Cross References in the sequence ID tooltip
1932 public void setShowDbRefs(boolean show)
1939 * @return true if Database References are to be displayed on tooltips.
1941 public boolean isShowDbRefs()
1948 * @return true if Non-positional features are to be displayed on tooltips.
1950 public boolean isShowNpFeats()
1955 * enable or disable the display of Non-Positional sequence features in the sequence ID tooltip
1958 public void setShowNpFeats(boolean show)
1964 * @return true if view has hidden rows
1966 public boolean hasHiddenRows()
1968 return hasHiddenRows;
1972 * @return true if view has hidden columns
1974 public boolean hasHiddenColumns()
1976 return hasHiddenColumns;
1979 * when set, view will scroll to show the highlighted position
1981 public boolean followHighlight=true;
1983 * @return true if view should scroll to show the highlighted region of a sequence
1986 public boolean getFollowHighlight() {
1987 return followHighlight;
1989 public boolean followSelection=true;
1991 * @return true if view selection should always follow the selections broadcast by other selection sources
1993 public boolean getFollowSelection() {
1994 return followSelection;
1996 private long sgrouphash=-1,colselhash=-1;
1998 boolean showSeqFeaturesHeight;
2000 * checks current SelectionGroup against record of last hash value, and updates record.
2001 * @return true if SelectionGroup changed since last call
2003 boolean isSelectionGroupChanged() {
2004 int hc=(selectionGroup==null) ? -1 : selectionGroup.hashCode();
2013 * checks current colsel against record of last hash value, and updates record.
2014 * @return true if colsel changed since last call
2016 boolean isColSelChanged() {
2017 int hc=(colSel==null) ? -1 : colSel.hashCode();
2025 public void sendSelection()
2027 jalview.structure.StructureSelectionManager.getStructureSelectionManager().sendSelection(new SequenceGroup(getSelectionGroup()), new ColumnSelection(getColumnSelection()), this);
2029 public void setShowSequenceFeaturesHeight(boolean selected)
2031 showSeqFeaturesHeight = selected;
2033 public boolean getShowSequenceFeaturesHeight()
2035 return showSeqFeaturesHeight;
2037 boolean showUnconserved=false;
2038 public boolean getShowUnconserved()
2040 return showUnconserved;
2042 public void setShowUnconserved(boolean showunconserved)
2044 showUnconserved=showunconserved;
2047 * return the alignPanel containing the given viewport. Use this to get the
2048 * components currently handling the given viewport.
2050 * @return null or an alignPanel guaranteed to have non-null alignFrame reference
2052 public AlignmentPanel getAlignPanel()
2054 AlignmentPanel[] aps = PaintRefresher.getAssociatedPanels(this.getSequenceSetId());
2055 AlignmentPanel ap=null;
2056 for (int p=0;aps!=null && p<aps.length; p++)
2058 if (aps[p].av == this)
2065 public boolean getSortByTree()
2069 public void setSortByTree(boolean sort) {
2073 * should conservation rows be shown for groups
2075 boolean showGroupConservation = false;
2077 * should consensus rows be shown for groups
2079 boolean showGroupConsensus = false;
2082 * @return the showGroupConservation
2084 public boolean isShowGroupConservation()
2086 return showGroupConservation;
2089 * @param showGroupConservation the showGroupConservation to set
2091 public void setShowGroupConservation(boolean showGroupConservation)
2093 this.showGroupConservation = showGroupConservation;
2096 * @return the showGroupConsensus
2098 public boolean isShowGroupConsensus()
2100 return showGroupConsensus;
2103 * @param showGroupConsensus the showGroupConsensus to set
2105 public void setShowGroupConsensus(boolean showGroupConsensus)
2107 this.showGroupConsensus = showGroupConsensus;