2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
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
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
21 package jalview.viewmodel;
23 import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
24 import jalview.analysis.Conservation;
25 import jalview.analysis.TreeModel;
26 import jalview.api.AlignCalcManagerI;
27 import jalview.api.AlignViewportI;
28 import jalview.api.AlignmentViewPanel;
29 import jalview.api.FeaturesDisplayedI;
30 import jalview.api.ViewStyleI;
31 import jalview.commands.CommandI;
32 import jalview.datamodel.AlignedCodonFrame;
33 import jalview.datamodel.AlignmentAnnotation;
34 import jalview.datamodel.AlignmentI;
35 import jalview.datamodel.AlignmentView;
36 import jalview.datamodel.Annotation;
37 import jalview.datamodel.ColumnSelection;
38 import jalview.datamodel.HiddenColumns;
39 import jalview.datamodel.HiddenSequences;
40 import jalview.datamodel.ProfilesI;
41 import jalview.datamodel.SearchResultsI;
42 import jalview.datamodel.Sequence;
43 import jalview.datamodel.SequenceCollectionI;
44 import jalview.datamodel.SequenceGroup;
45 import jalview.datamodel.SequenceI;
46 import jalview.renderer.ResidueShader;
47 import jalview.renderer.ResidueShaderI;
48 import jalview.schemes.ColourSchemeI;
49 import jalview.structure.CommandListener;
50 import jalview.structure.StructureSelectionManager;
51 import jalview.structure.VamsasSource;
52 import jalview.util.Comparison;
53 import jalview.util.MapList;
54 import jalview.util.MappingUtils;
55 import jalview.util.MessageManager;
56 import jalview.viewmodel.styles.ViewStyle;
57 import jalview.workers.AlignCalcManager;
58 import jalview.workers.ComplementConsensusThread;
59 import jalview.workers.ConsensusThread;
60 import jalview.workers.InformationThread;
61 import jalview.workers.StrucConsensusThread;
63 import java.awt.Color;
64 import java.beans.PropertyChangeSupport;
65 import java.util.ArrayDeque;
66 import java.util.ArrayList;
67 import java.util.BitSet;
68 import java.util.Deque;
69 import java.util.HashMap;
70 import java.util.Hashtable;
71 import java.util.Iterator;
72 import java.util.List;
76 * base class holding visualization and analysis attributes and common logic for
77 * an active alignment view displayed in the GUI
82 public abstract class AlignmentViewport
83 implements AlignViewportI, CommandListener, VamsasSource
85 protected ViewportRanges ranges;
87 protected ViewStyleI viewStyle = new ViewStyle();
90 * A viewport that hosts the cDna view of this (protein), or vice versa (if
93 AlignViewportI codingComplement = null;
95 FeaturesDisplayedI featuresDisplayed = null;
97 protected Deque<CommandI> historyList = new ArrayDeque<>();
99 protected Deque<CommandI> redoList = new ArrayDeque<>();
102 * alignment displayed in the viewport. Please use get/setter
104 protected AlignmentI alignment;
107 * probably unused indicator that view is of a dataset rather than an
111 protected boolean ignoreBelowBackGroundFrequencyCalculation = false;
113 protected boolean infoLetterHeight = false;
115 protected AlignmentAnnotation occupancy;
118 * results of alignment consensus analysis for visible portion of view
120 protected ProfilesI consensusProfiles;
123 * HMM profile for the alignment
125 protected ProfilesI hmmProfiles;
127 public AlignmentViewport(AlignmentI al)
130 ranges = new ViewportRanges(al);
135 * @see jalview.api.ViewStyleI#setFontName(java.lang.String)
138 public void setFontName(String name)
140 viewStyle.setFontName(name);
145 * @see jalview.api.ViewStyleI#setFontStyle(int)
148 public void setFontStyle(int style)
150 viewStyle.setFontStyle(style);
155 * @see jalview.api.ViewStyleI#setFontSize(int)
158 public void setFontSize(int size)
160 viewStyle.setFontSize(size);
165 * @see jalview.api.ViewStyleI#getFontStyle()
168 public int getFontStyle()
170 return viewStyle.getFontStyle();
175 * @see jalview.api.ViewStyleI#getFontName()
178 public String getFontName()
180 return viewStyle.getFontName();
185 * @see jalview.api.ViewStyleI#getFontSize()
188 public int getFontSize()
190 return viewStyle.getFontSize();
194 * @param upperCasebold
195 * @see jalview.api.ViewStyleI#setUpperCasebold(boolean)
198 public void setUpperCasebold(boolean upperCasebold)
200 viewStyle.setUpperCasebold(upperCasebold);
205 * @see jalview.api.ViewStyleI#isUpperCasebold()
208 public boolean isUpperCasebold()
210 return viewStyle.isUpperCasebold();
215 * @see jalview.api.ViewStyleI#isSeqNameItalics()
218 public boolean isSeqNameItalics()
220 return viewStyle.isSeqNameItalics();
224 * @param colourByReferenceSeq
225 * @see jalview.api.ViewStyleI#setColourByReferenceSeq(boolean)
228 public void setColourByReferenceSeq(boolean colourByReferenceSeq)
230 viewStyle.setColourByReferenceSeq(colourByReferenceSeq);
235 * @see jalview.api.ViewStyleI#setColourAppliesToAllGroups(boolean)
238 public void setColourAppliesToAllGroups(boolean b)
240 viewStyle.setColourAppliesToAllGroups(b);
245 * @see jalview.api.ViewStyleI#getColourAppliesToAllGroups()
248 public boolean getColourAppliesToAllGroups()
250 return viewStyle.getColourAppliesToAllGroups();
255 * @see jalview.api.ViewStyleI#getAbovePIDThreshold()
258 public boolean getAbovePIDThreshold()
260 return viewStyle.getAbovePIDThreshold();
265 * @see jalview.api.ViewStyleI#setIncrement(int)
268 public void setIncrement(int inc)
270 viewStyle.setIncrement(inc);
275 * @see jalview.api.ViewStyleI#getIncrement()
278 public int getIncrement()
280 return viewStyle.getIncrement();
285 * @see jalview.api.ViewStyleI#setConservationSelected(boolean)
288 public void setConservationSelected(boolean b)
290 viewStyle.setConservationSelected(b);
295 * @see jalview.api.ViewStyleI#setShowHiddenMarkers(boolean)
298 public void setShowHiddenMarkers(boolean show)
300 viewStyle.setShowHiddenMarkers(show);
305 * @see jalview.api.ViewStyleI#getShowHiddenMarkers()
308 public boolean getShowHiddenMarkers()
310 return viewStyle.getShowHiddenMarkers();
315 * @see jalview.api.ViewStyleI#setScaleRightWrapped(boolean)
318 public void setScaleRightWrapped(boolean b)
320 viewStyle.setScaleRightWrapped(b);
325 * @see jalview.api.ViewStyleI#setScaleLeftWrapped(boolean)
328 public void setScaleLeftWrapped(boolean b)
330 viewStyle.setScaleLeftWrapped(b);
335 * @see jalview.api.ViewStyleI#setScaleAboveWrapped(boolean)
338 public void setScaleAboveWrapped(boolean b)
340 viewStyle.setScaleAboveWrapped(b);
345 * @see jalview.api.ViewStyleI#getScaleLeftWrapped()
348 public boolean getScaleLeftWrapped()
350 return viewStyle.getScaleLeftWrapped();
355 * @see jalview.api.ViewStyleI#getScaleAboveWrapped()
358 public boolean getScaleAboveWrapped()
360 return viewStyle.getScaleAboveWrapped();
365 * @see jalview.api.ViewStyleI#getScaleRightWrapped()
368 public boolean getScaleRightWrapped()
370 return viewStyle.getScaleRightWrapped();
375 * @see jalview.api.ViewStyleI#setAbovePIDThreshold(boolean)
378 public void setAbovePIDThreshold(boolean b)
380 viewStyle.setAbovePIDThreshold(b);
385 * @see jalview.api.ViewStyleI#setThreshold(int)
388 public void setThreshold(int thresh)
390 viewStyle.setThreshold(thresh);
395 * @see jalview.api.ViewStyleI#getThreshold()
398 public int getThreshold()
400 return viewStyle.getThreshold();
405 * @see jalview.api.ViewStyleI#getShowJVSuffix()
408 public boolean getShowJVSuffix()
410 return viewStyle.getShowJVSuffix();
415 * @see jalview.api.ViewStyleI#setShowJVSuffix(boolean)
418 public void setShowJVSuffix(boolean b)
420 viewStyle.setShowJVSuffix(b);
425 * @see jalview.api.ViewStyleI#setWrapAlignment(boolean)
428 public void setWrapAlignment(boolean state)
430 viewStyle.setWrapAlignment(state);
431 ranges.setWrappedMode(state);
436 * @see jalview.api.ViewStyleI#setShowText(boolean)
439 public void setShowText(boolean state)
441 viewStyle.setShowText(state);
446 * @see jalview.api.ViewStyleI#setRenderGaps(boolean)
449 public void setRenderGaps(boolean state)
451 viewStyle.setRenderGaps(state);
456 * @see jalview.api.ViewStyleI#getColourText()
459 public boolean getColourText()
461 return viewStyle.getColourText();
466 * @see jalview.api.ViewStyleI#setColourText(boolean)
469 public void setColourText(boolean state)
471 viewStyle.setColourText(state);
476 * @see jalview.api.ViewStyleI#getWrapAlignment()
479 public boolean getWrapAlignment()
481 return viewStyle.getWrapAlignment();
486 * @see jalview.api.ViewStyleI#getShowText()
489 public boolean getShowText()
491 return viewStyle.getShowText();
496 * @see jalview.api.ViewStyleI#getWrappedWidth()
499 public int getWrappedWidth()
501 return viewStyle.getWrappedWidth();
506 * @see jalview.api.ViewStyleI#setWrappedWidth(int)
509 public void setWrappedWidth(int w)
511 viewStyle.setWrappedWidth(w);
516 * @see jalview.api.ViewStyleI#getCharHeight()
519 public int getCharHeight()
521 return viewStyle.getCharHeight();
526 * @see jalview.api.ViewStyleI#setCharHeight(int)
529 public void setCharHeight(int h)
531 viewStyle.setCharHeight(h);
536 * @see jalview.api.ViewStyleI#getCharWidth()
539 public int getCharWidth()
541 return viewStyle.getCharWidth();
546 * @see jalview.api.ViewStyleI#setCharWidth(int)
549 public void setCharWidth(int w)
551 viewStyle.setCharWidth(w);
556 * @see jalview.api.ViewStyleI#getShowBoxes()
559 public boolean getShowBoxes()
561 return viewStyle.getShowBoxes();
566 * @see jalview.api.ViewStyleI#getShowUnconserved()
569 public boolean getShowUnconserved()
571 return viewStyle.getShowUnconserved();
575 * @param showunconserved
576 * @see jalview.api.ViewStyleI#setShowUnconserved(boolean)
579 public void setShowUnconserved(boolean showunconserved)
581 viewStyle.setShowUnconserved(showunconserved);
586 * @see jalview.api.ViewStyleI#setSeqNameItalics(boolean)
589 public void setSeqNameItalics(boolean default1)
591 viewStyle.setSeqNameItalics(default1);
595 public AlignmentI getAlignment()
601 public char getGapCharacter()
603 return alignment.getGapCharacter();
606 protected String sequenceSetID;
609 * probably unused indicator that view is of a dataset rather than an
612 protected boolean isDataset = false;
614 public void setDataset(boolean b)
619 public boolean isDataset()
624 private Map<SequenceI, SequenceCollectionI> hiddenRepSequences;
626 protected ColumnSelection colSel = new ColumnSelection();
628 public boolean autoCalculateConsensus = true;
630 protected boolean autoCalculateStrucConsensus = true;
632 protected boolean ignoreGapsInConsensusCalculation = false;
634 protected ResidueShaderI residueShading = new ResidueShader();
637 public void setGlobalColourScheme(ColourSchemeI cs)
639 // TODO: logic refactored from AlignFrame changeColour -
640 // TODO: autorecalc stuff should be changed to rely on the worker system
641 // check to see if we should implement a changeColour(cs) method rather than
642 // put the logic in here
643 // - means that caller decides if they want to just modify state and defer
644 // calculation till later or to do all calculations in thread.
648 * only instantiate alignment colouring once, thereafter update it;
649 * this means that any conservation or PID threshold settings
650 * persist when the alignment colour scheme is changed
652 if (residueShading == null)
654 residueShading = new ResidueShader(viewStyle);
656 residueShading.setColourScheme(cs);
658 // TODO: do threshold and increment belong in ViewStyle or ResidueShader?
659 // ...problem: groups need these, but do not currently have a ViewStyle
663 if (getConservationSelected())
665 residueShading.setConservation(hconservation);
668 * reset conservation flag in case just set to false if
669 * Conservation was null (calculation still in progress)
671 residueShading.setConservationApplied(getConservationSelected());
672 residueShading.alignmentChanged(alignment, hiddenRepSequences);
676 * if 'apply colour to all groups' is selected... do so
677 * (but don't transfer any colour threshold settings to groups)
679 if (getColourAppliesToAllGroups())
681 for (SequenceGroup sg : getAlignment().getGroups())
684 * retain any colour thresholds per group while
685 * changing choice of colour scheme (JAL-2386)
688 cs == null ? null : cs.getInstance(this, sg));
691 sg.getGroupColourScheme().alignmentChanged(sg,
699 public ColourSchemeI getGlobalColourScheme()
701 return residueShading == null ? null : residueShading.getColourScheme();
705 public ResidueShaderI getResidueShading()
707 return residueShading;
710 protected AlignmentAnnotation consensus;
712 protected AlignmentAnnotation complementConsensus;
714 protected AlignmentAnnotation gapcounts;
716 protected AlignmentAnnotation strucConsensus;
718 protected AlignmentAnnotation conservation;
720 protected AlignmentAnnotation quality;
722 protected AlignmentAnnotation[] groupConsensus;
724 protected AlignmentAnnotation[] groupConservation;
727 * results of alignment consensus analysis for visible portion of view
729 protected ProfilesI hconsensus = null;
732 * results of cDNA complement consensus visible portion of view
734 protected Hashtable[] hcomplementConsensus = null;
737 * results of secondary structure base pair consensus for visible portion of
740 protected Hashtable[] hStrucConsensus = null;
742 protected Conservation hconservation = null;
745 public void setConservation(Conservation cons)
747 hconservation = cons;
751 * percentage gaps allowed in a column before all amino acid properties should
752 * be considered unconserved
754 int ConsPercGaps = 25; // JBPNote : This should be a scalable property!
757 public int getConsPercGaps()
763 public void setSequenceConsensusHash(ProfilesI hconsensus)
765 this.hconsensus = hconsensus;
769 public void setComplementConsensusHash(Hashtable[] hconsensus)
771 this.hcomplementConsensus = hconsensus;
775 public ProfilesI getSequenceConsensusHash()
781 public void setHmmProfiles(ProfilesI info)
787 public ProfilesI getHmmProfiles()
793 public Hashtable[] getComplementConsensusHash()
795 return hcomplementConsensus;
799 public Hashtable[] getRnaStructureConsensusHash()
801 return hStrucConsensus;
805 public void setRnaStructureConsensusHash(Hashtable[] hStrucConsensus)
807 this.hStrucConsensus = hStrucConsensus;
812 public AlignmentAnnotation getAlignmentQualityAnnot()
818 public AlignmentAnnotation getAlignmentConservationAnnotation()
824 public AlignmentAnnotation getAlignmentConsensusAnnotation()
830 public AlignmentAnnotation getAlignmentGapAnnotation()
836 public AlignmentAnnotation getComplementConsensusAnnotation()
838 return complementConsensus;
842 public AlignmentAnnotation getAlignmentStrucConsensusAnnotation()
844 return strucConsensus;
847 protected AlignCalcManagerI calculator = new AlignCalcManager();
850 * trigger update of conservation annotation
852 public void updateConservation(final AlignmentViewPanel ap)
854 // see note in mantis : issue number 8585
855 if (alignment.isNucleotide()
856 || (conservation == null && quality == null)
857 || !autoCalculateConsensus)
861 if (calculator.getRegisteredWorkersOfClass(
862 jalview.workers.ConservationThread.class) == null)
864 calculator.registerWorker(
865 new jalview.workers.ConservationThread(this, ap));
870 * trigger update of consensus annotation
872 public void updateConsensus(final AlignmentViewPanel ap)
874 // see note in mantis : issue number 8585
875 if (consensus == null || !autoCalculateConsensus)
880 .getRegisteredWorkersOfClass(ConsensusThread.class) == null)
882 calculator.registerWorker(new ConsensusThread(this, ap));
886 * A separate thread to compute cDNA consensus for a protein alignment
887 * which has mapping to cDNA
889 final AlignmentI al = this.getAlignment();
890 if (!al.isNucleotide() && al.getCodonFrames() != null
891 && !al.getCodonFrames().isEmpty())
894 * fudge - check first for protein-to-nucleotide mappings
895 * (we don't want to do this for protein-to-protein)
897 boolean doConsensus = false;
898 for (AlignedCodonFrame mapping : al.getCodonFrames())
900 // TODO hold mapping type e.g. dna-to-protein in AlignedCodonFrame?
901 MapList[] mapLists = mapping.getdnaToProt();
902 // mapLists can be empty if project load has not finished resolving seqs
903 if (mapLists.length > 0 && mapLists[0].getFromRatio() == 3)
911 if (calculator.getRegisteredWorkersOfClass(
912 ComplementConsensusThread.class) == null)
915 .registerWorker(new ComplementConsensusThread(this, ap));
922 public void initInformationWorker(final AlignmentViewPanel ap)
925 .getRegisteredWorkersOfClass(InformationThread.class) == null)
927 calculator.registerWorker(new InformationThread(this, ap));
931 // --------START Structure Conservation
932 public void updateStrucConsensus(final AlignmentViewPanel ap)
934 if (autoCalculateStrucConsensus && strucConsensus == null
935 && alignment.isNucleotide() && alignment.hasRNAStructure())
937 // secondary structure has been added - so init the consensus line
941 // see note in mantis : issue number 8585
942 if (strucConsensus == null || !autoCalculateStrucConsensus)
946 if (calculator.getRegisteredWorkersOfClass(
947 StrucConsensusThread.class) == null)
949 calculator.registerWorker(new StrucConsensusThread(this, ap));
953 public boolean isCalcInProgress()
955 return calculator.isWorking();
959 public boolean isCalculationInProgress(
960 AlignmentAnnotation alignmentAnnotation)
962 if (!alignmentAnnotation.autoCalculated)
966 if (calculator.workingInvolvedWith(alignmentAnnotation))
968 // System.err.println("grey out ("+alignmentAnnotation.label+")");
974 public void setAlignment(AlignmentI align)
976 this.alignment = align;
980 * Clean up references when this viewport is closed
983 public void dispose()
986 * defensively null out references to large objects in case
987 * this object is not garbage collected (as if!)
990 complementConsensus = null;
991 strucConsensus = null;
994 consensusProfiles = null;
995 groupConsensus = null;
996 groupConservation = null;
998 hconservation = null;
999 hcomplementConsensus = null;
1002 residueShading = null; // may hold a reference to Consensus
1003 changeSupport = null;
1006 selectionGroup = null;
1011 public boolean isClosed()
1013 // TODO: check that this isClosed is only true after panel is closed, not
1014 // before it is fully constructed.
1015 return alignment == null;
1019 public AlignCalcManagerI getCalcManager()
1025 * should conservation rows be shown for groups
1027 protected boolean showGroupConservation = false;
1030 * should consensus rows be shown for groups
1032 protected boolean showGroupConsensus = false;
1035 * should consensus profile be rendered by default
1037 protected boolean showSequenceLogo = false;
1040 * should consensus profile be rendered normalised to row height
1042 protected boolean normaliseSequenceLogo = false;
1045 * should consensus histograms be rendered by default
1047 protected boolean showConsensusHistogram = true;
1050 * should hmm profile be rendered by default
1052 protected boolean hmmShowSequenceLogo = false;
1055 * should hmm profile be rendered normalised to row height
1057 protected boolean hmmNormaliseSequenceLogo = false;
1060 * should information histograms be rendered by default
1062 protected boolean hmmShowHistogram = true;
1065 * @return the showConsensusProfile
1068 public boolean isShowSequenceLogo()
1070 return showSequenceLogo;
1074 * @return the showInformationProfile
1077 public boolean isShowHMMSequenceLogo()
1079 return hmmShowSequenceLogo;
1083 * @param showSequenceLogo
1086 public void setShowSequenceLogo(boolean showSequenceLogo)
1088 if (showSequenceLogo != this.showSequenceLogo)
1090 // TODO: decouple settings setting from calculation when refactoring
1091 // annotation update method from alignframe to viewport
1092 this.showSequenceLogo = showSequenceLogo;
1093 calculator.updateAnnotationFor(ConsensusThread.class);
1094 calculator.updateAnnotationFor(ComplementConsensusThread.class);
1095 calculator.updateAnnotationFor(StrucConsensusThread.class);
1097 this.showSequenceLogo = showSequenceLogo;
1100 public void setShowHMMSequenceLogo(boolean showHMMSequenceLogo)
1102 if (showHMMSequenceLogo != this.hmmShowSequenceLogo)
1104 this.hmmShowSequenceLogo = showHMMSequenceLogo;
1105 // TODO: updateAnnotation if description (tooltip) will show
1106 // profile in place of information content?
1107 // calculator.updateAnnotationFor(InformationThread.class);
1109 this.hmmShowSequenceLogo = showHMMSequenceLogo;
1113 * @param showConsensusHistogram
1114 * the showConsensusHistogram to set
1116 public void setShowConsensusHistogram(boolean showConsensusHistogram)
1118 this.showConsensusHistogram = showConsensusHistogram;
1122 * @param showInformationHistogram
1124 public void setShowInformationHistogram(boolean showInformationHistogram)
1126 this.hmmShowHistogram = showInformationHistogram;
1130 * @return the showGroupConservation
1132 public boolean isShowGroupConservation()
1134 return showGroupConservation;
1138 * @param showGroupConservation
1139 * the showGroupConservation to set
1141 public void setShowGroupConservation(boolean showGroupConservation)
1143 this.showGroupConservation = showGroupConservation;
1147 * @return the showGroupConsensus
1149 public boolean isShowGroupConsensus()
1151 return showGroupConsensus;
1155 * @param showGroupConsensus
1156 * the showGroupConsensus to set
1158 public void setShowGroupConsensus(boolean showGroupConsensus)
1160 this.showGroupConsensus = showGroupConsensus;
1165 * @return flag to indicate if the consensus histogram should be rendered by
1169 public boolean isShowConsensusHistogram()
1171 return this.showConsensusHistogram;
1176 * @return flag to indicate if the information content histogram should be
1177 * rendered by default
1180 public boolean isShowInformationHistogram()
1182 return this.hmmShowHistogram;
1186 * when set, updateAlignment will always ensure sequences are of equal length
1188 private boolean padGaps = false;
1191 * when set, alignment should be reordered according to a newly opened tree
1193 public boolean sortByTree = false;
1198 * @return null or the currently selected sequence region
1201 public SequenceGroup getSelectionGroup()
1203 return selectionGroup;
1207 * Set the selection group for this window. Also sets the current alignment as
1208 * the context for the group, if it does not already have one.
1211 * - group holding references to sequences in this alignment view
1215 public void setSelectionGroup(SequenceGroup sg)
1217 selectionGroup = sg;
1218 if (sg != null && sg.getContext() == null)
1220 sg.setContext(alignment);
1224 public void setHiddenColumns(HiddenColumns hidden)
1226 this.alignment.setHiddenColumns(hidden);
1230 public ColumnSelection getColumnSelection()
1236 public void setColumnSelection(ColumnSelection colSel)
1238 this.colSel = colSel;
1241 updateHiddenColumns();
1243 isColSelChanged(true);
1251 public Map<SequenceI, SequenceCollectionI> getHiddenRepSequences()
1253 return hiddenRepSequences;
1257 public void setHiddenRepSequences(
1258 Map<SequenceI, SequenceCollectionI> hiddenRepSequences)
1260 this.hiddenRepSequences = hiddenRepSequences;
1264 public boolean hasSelectedColumns()
1266 ColumnSelection columnSelection = getColumnSelection();
1267 return columnSelection != null && columnSelection.hasSelectedColumns();
1271 public boolean hasHiddenColumns()
1273 return alignment.getHiddenColumns() != null
1274 && alignment.getHiddenColumns().hasHiddenColumns();
1277 public void updateHiddenColumns()
1279 // this method doesn't really do anything now. But - it could, since a
1280 // column Selection could be in the process of modification
1281 // hasHiddenColumns = colSel.hasHiddenColumns();
1285 public boolean hasHiddenRows()
1287 return alignment.getHiddenSequences().getSize() > 0;
1290 protected SequenceGroup selectionGroup;
1292 public void setSequenceSetId(String newid)
1294 if (sequenceSetID != null)
1297 "Warning - overwriting a sequenceSetId for a viewport!");
1299 sequenceSetID = new String(newid);
1303 public String getSequenceSetId()
1305 if (sequenceSetID == null)
1307 sequenceSetID = alignment.hashCode() + "";
1310 return sequenceSetID;
1314 * unique viewId for synchronizing state (e.g. with stored Jalview Project)
1317 protected String viewId = null;
1320 public String getViewId()
1324 viewId = this.getSequenceSetId() + "." + this.hashCode() + "";
1329 public void setIgnoreGapsConsensus(boolean b, AlignmentViewPanel ap)
1331 ignoreGapsInConsensusCalculation = b;
1334 updateConsensus(ap);
1335 if (residueShading != null)
1337 residueShading.setThreshold(residueShading.getThreshold(),
1338 ignoreGapsInConsensusCalculation);
1343 public void setIgnoreBelowBackground(boolean b, AlignmentViewPanel ap)
1345 ignoreBelowBackGroundFrequencyCalculation = b;
1348 public void setInfoLetterHeight(boolean b, AlignmentViewPanel ap)
1350 infoLetterHeight = b;
1353 private long sgrouphash = -1, colselhash = -1;
1356 * checks current SelectionGroup against record of last hash value, and
1360 * update the record of last hash value
1362 * @return true if SelectionGroup changed since last call (when b is true)
1364 public boolean isSelectionGroupChanged(boolean b)
1366 int hc = (selectionGroup == null || selectionGroup.getSize() == 0) ? -1
1367 : selectionGroup.hashCode();
1368 if (hc != -1 && hc != sgrouphash)
1380 * checks current colsel against record of last hash value, and optionally
1384 * update the record of last hash value
1385 * @return true if colsel changed since last call (when b is true)
1387 public boolean isColSelChanged(boolean b)
1389 int hc = (colSel == null || colSel.isEmpty()) ? -1 : colSel.hashCode();
1390 if (hc != -1 && hc != colselhash)
1402 public boolean isIgnoreGapsConsensus()
1404 return ignoreGapsInConsensusCalculation;
1408 public boolean isIgnoreBelowBackground()
1410 return ignoreBelowBackGroundFrequencyCalculation;
1414 public boolean isInfoLetterHeight()
1416 return infoLetterHeight;
1419 // property change stuff
1420 // JBPNote Prolly only need this in the applet version.
1421 private PropertyChangeSupport changeSupport = new PropertyChangeSupport(
1424 protected boolean showConservation = true;
1426 protected boolean showQuality = true;
1428 protected boolean showConsensus = true;
1430 protected boolean showOccupancy = true;
1432 private Map<SequenceI, Color> sequenceColours = new HashMap<>();
1434 protected SequenceAnnotationOrder sortAnnotationsBy = null;
1436 protected boolean showAutocalculatedAbove;
1439 * when set, view will scroll to show the highlighted position
1441 private boolean followHighlight = true;
1444 * Property change listener for changes in alignment
1449 public void addPropertyChangeListener(
1450 java.beans.PropertyChangeListener listener)
1452 changeSupport.addPropertyChangeListener(listener);
1461 public void removePropertyChangeListener(
1462 java.beans.PropertyChangeListener listener)
1464 if (changeSupport != null)
1466 changeSupport.removePropertyChangeListener(listener);
1471 * Property change listener for changes in alignment
1480 public void firePropertyChange(String prop, Object oldvalue,
1483 changeSupport.firePropertyChange(prop, oldvalue, newvalue);
1486 // common hide/show column stuff
1488 public void hideSelectedColumns()
1490 if (colSel.isEmpty())
1495 colSel.hideSelectedColumns(alignment);
1496 setSelectionGroup(null);
1497 isColSelChanged(true);
1500 public void hideColumns(int start, int end)
1504 colSel.hideSelectedColumns(start, alignment.getHiddenColumns());
1508 alignment.getHiddenColumns().hideColumns(start, end);
1510 isColSelChanged(true);
1513 public void showColumn(int col)
1515 alignment.getHiddenColumns().revealHiddenColumns(col, colSel);
1516 isColSelChanged(true);
1519 public void showAllHiddenColumns()
1521 alignment.getHiddenColumns().revealAllHiddenColumns(colSel);
1522 isColSelChanged(true);
1525 // common hide/show seq stuff
1526 public void showAllHiddenSeqs()
1528 int startSeq = ranges.getStartSeq();
1529 int endSeq = ranges.getEndSeq();
1531 if (alignment.getHiddenSequences().getSize() > 0)
1533 if (selectionGroup == null)
1535 selectionGroup = new SequenceGroup();
1536 selectionGroup.setEndRes(alignment.getWidth() - 1);
1538 List<SequenceI> tmp = alignment.getHiddenSequences()
1539 .showAll(hiddenRepSequences);
1540 for (SequenceI seq : tmp)
1542 selectionGroup.addSequence(seq, false);
1543 setSequenceAnnotationsVisible(seq, true);
1546 hiddenRepSequences = null;
1548 ranges.setStartEndSeq(startSeq, endSeq + tmp.size());
1550 firePropertyChange("alignment", null, alignment.getSequences());
1551 // used to set hasHiddenRows/hiddenRepSequences here, after the property
1557 public void showSequence(int index)
1559 int startSeq = ranges.getStartSeq();
1560 int endSeq = ranges.getEndSeq();
1562 List<SequenceI> tmp = alignment.getHiddenSequences().showSequence(index,
1563 hiddenRepSequences);
1566 if (selectionGroup == null)
1568 selectionGroup = new SequenceGroup();
1569 selectionGroup.setEndRes(alignment.getWidth() - 1);
1572 for (SequenceI seq : tmp)
1574 selectionGroup.addSequence(seq, false);
1575 setSequenceAnnotationsVisible(seq, true);
1578 ranges.setStartEndSeq(startSeq, endSeq + tmp.size());
1580 firePropertyChange("alignment", null, alignment.getSequences());
1585 public void hideAllSelectedSeqs()
1587 if (selectionGroup == null || selectionGroup.getSize() < 1)
1592 SequenceI[] seqs = selectionGroup.getSequencesInOrder(alignment);
1596 setSelectionGroup(null);
1599 public void hideSequence(SequenceI[] seq)
1602 * cache offset to first visible sequence
1604 int startSeq = ranges.getStartSeq();
1608 for (int i = 0; i < seq.length; i++)
1610 alignment.getHiddenSequences().hideSequence(seq[i]);
1611 setSequenceAnnotationsVisible(seq[i], false);
1613 ranges.setStartSeq(startSeq);
1614 firePropertyChange("alignment", null, alignment.getSequences());
1619 * Hides the specified sequence, or the sequences it represents
1622 * the sequence to hide, or keep as representative
1623 * @param representGroup
1624 * if true, hide the current selection group except for the
1625 * representative sequence
1627 public void hideSequences(SequenceI sequence, boolean representGroup)
1629 if (selectionGroup == null || selectionGroup.getSize() < 1)
1631 hideSequence(new SequenceI[] { sequence });
1637 hideRepSequences(sequence, selectionGroup);
1638 setSelectionGroup(null);
1642 int gsize = selectionGroup.getSize();
1643 SequenceI[] hseqs = selectionGroup.getSequences()
1644 .toArray(new SequenceI[gsize]);
1646 hideSequence(hseqs);
1647 setSelectionGroup(null);
1652 * Set visibility for any annotations for the given sequence.
1656 protected void setSequenceAnnotationsVisible(SequenceI sequenceI,
1659 AlignmentAnnotation[] anns = alignment.getAlignmentAnnotation();
1662 for (AlignmentAnnotation ann : anns)
1664 if (ann.sequenceRef == sequenceI)
1666 ann.visible = visible;
1672 public void hideRepSequences(SequenceI repSequence, SequenceGroup sg)
1674 int sSize = sg.getSize();
1680 if (hiddenRepSequences == null)
1682 hiddenRepSequences = new Hashtable<>();
1685 hiddenRepSequences.put(repSequence, sg);
1687 // Hide all sequences except the repSequence
1688 SequenceI[] seqs = new SequenceI[sSize - 1];
1690 for (int i = 0; i < sSize; i++)
1692 if (sg.getSequenceAt(i) != repSequence)
1694 if (index == sSize - 1)
1699 seqs[index++] = sg.getSequenceAt(i);
1702 sg.setSeqrep(repSequence); // note: not done in 2.7applet
1703 sg.setHidereps(true); // note: not done in 2.7applet
1710 * @return null or the current reference sequence
1712 public SequenceI getReferenceSeq()
1714 return alignment.getSeqrep();
1719 * @return true iff seq is the reference for the alignment
1721 public boolean isReferenceSeq(SequenceI seq)
1723 return alignment.getSeqrep() == seq;
1729 * @return true if there are sequences represented by this sequence that are
1732 public boolean isHiddenRepSequence(SequenceI seq)
1734 return (hiddenRepSequences != null
1735 && hiddenRepSequences.containsKey(seq));
1741 * @return null or a sequence group containing the sequences that seq
1744 public SequenceGroup getRepresentedSequences(SequenceI seq)
1746 return (SequenceGroup) (hiddenRepSequences == null ? null
1747 : hiddenRepSequences.get(seq));
1751 public int adjustForHiddenSeqs(int alignmentIndex)
1753 return alignment.getHiddenSequences()
1754 .adjustForHiddenSeqs(alignmentIndex);
1758 public void invertColumnSelection()
1760 colSel.invertColumnSelection(0, alignment.getWidth(), alignment);
1761 isColSelChanged(true);
1765 public SequenceI[] getSelectionAsNewSequence()
1767 SequenceI[] sequences;
1768 // JBPNote: Need to test jalviewLite.getSelectedSequencesAsAlignmentFrom -
1769 // this was the only caller in the applet for this method
1770 // JBPNote: in applet, this method returned references to the alignment
1771 // sequences, and it did not honour the presence/absence of annotation
1772 // attached to the alignment (probably!)
1773 if (selectionGroup == null || selectionGroup.getSize() == 0)
1775 sequences = alignment.getSequencesArray();
1776 AlignmentAnnotation[] annots = alignment.getAlignmentAnnotation();
1777 for (int i = 0; i < sequences.length; i++)
1779 // construct new sequence with subset of visible annotation
1780 sequences[i] = new Sequence(sequences[i], annots);
1785 sequences = selectionGroup.getSelectionAsNewSequences(alignment);
1792 public SequenceI[] getSequenceSelection()
1794 SequenceI[] sequences = null;
1795 if (selectionGroup != null)
1797 sequences = selectionGroup.getSequencesInOrder(alignment);
1799 if (sequences == null)
1801 sequences = alignment.getSequencesArray();
1807 public jalview.datamodel.AlignmentView getAlignmentView(
1808 boolean selectedOnly)
1810 return getAlignmentView(selectedOnly, false);
1814 public jalview.datamodel.AlignmentView getAlignmentView(
1815 boolean selectedOnly, boolean markGroups)
1817 return new AlignmentView(alignment, alignment.getHiddenColumns(),
1819 alignment.getHiddenColumns() != null
1820 && alignment.getHiddenColumns().hasHiddenColumns(),
1821 selectedOnly, markGroups);
1825 public String[] getViewAsString(boolean selectedRegionOnly)
1827 return getViewAsString(selectedRegionOnly, true);
1831 public String[] getViewAsString(boolean selectedRegionOnly,
1832 boolean exportHiddenSeqs)
1834 String[] selection = null;
1835 SequenceI[] seqs = null;
1837 int start = 0, end = 0;
1838 if (selectedRegionOnly && selectionGroup != null)
1840 iSize = selectionGroup.getSize();
1841 seqs = selectionGroup.getSequencesInOrder(alignment);
1842 start = selectionGroup.getStartRes();
1843 end = selectionGroup.getEndRes() + 1;
1847 if (hasHiddenRows() && exportHiddenSeqs)
1849 AlignmentI fullAlignment = alignment.getHiddenSequences()
1850 .getFullAlignment();
1851 iSize = fullAlignment.getHeight();
1852 seqs = fullAlignment.getSequencesArray();
1853 end = fullAlignment.getWidth();
1857 iSize = alignment.getHeight();
1858 seqs = alignment.getSequencesArray();
1859 end = alignment.getWidth();
1863 selection = new String[iSize];
1864 if (alignment.getHiddenColumns() != null
1865 && alignment.getHiddenColumns().hasHiddenColumns())
1867 for (i = 0; i < iSize; i++)
1869 Iterator<int[]> blocks = alignment.getHiddenColumns()
1870 .getVisContigsIterator(start, end + 1, false);
1871 selection[i] = seqs[i].getSequenceStringFromIterator(blocks);
1876 for (i = 0; i < iSize; i++)
1878 selection[i] = seqs[i].getSequenceAsString(start, end);
1886 public List<int[]> getVisibleRegionBoundaries(int min, int max)
1888 ArrayList<int[]> regions = new ArrayList<>();
1894 HiddenColumns hidden = alignment.getHiddenColumns();
1895 if (hidden != null && hidden.hasHiddenColumns())
1899 start = hidden.visibleToAbsoluteColumn(start);
1902 end = hidden.getNextHiddenBoundary(false, start);
1913 regions.add(new int[] { start, end });
1915 if (hidden != null && hidden.hasHiddenColumns())
1917 start = hidden.visibleToAbsoluteColumn(end);
1918 start = hidden.getNextHiddenBoundary(true, start) + 1;
1920 } while (end < max);
1922 int[][] startEnd = new int[regions.size()][2];
1928 public List<AlignmentAnnotation> getVisibleAlignmentAnnotation(
1929 boolean selectedOnly)
1931 ArrayList<AlignmentAnnotation> ala = new ArrayList<>();
1932 AlignmentAnnotation[] aa;
1933 if ((aa = alignment.getAlignmentAnnotation()) != null)
1935 for (AlignmentAnnotation annot : aa)
1937 AlignmentAnnotation clone = new AlignmentAnnotation(annot);
1938 if (selectedOnly && selectionGroup != null)
1940 clone.makeVisibleAnnotation(
1941 selectionGroup.getStartRes(), selectionGroup.getEndRes(),
1942 alignment.getHiddenColumns());
1946 clone.makeVisibleAnnotation(alignment.getHiddenColumns());
1955 public boolean isPadGaps()
1961 public void setPadGaps(boolean padGaps)
1963 this.padGaps = padGaps;
1967 * apply any post-edit constraints and trigger any calculations needed after
1968 * an edit has been performed on the alignment
1973 public void alignmentChanged(AlignmentViewPanel ap)
1977 alignment.padGaps();
1979 if (autoCalculateConsensus)
1981 updateConsensus(ap);
1983 if (hconsensus != null && autoCalculateConsensus)
1985 updateConservation(ap);
1987 if (autoCalculateStrucConsensus)
1989 updateStrucConsensus(ap);
1992 // Reset endRes of groups if beyond alignment width
1993 int alWidth = alignment.getWidth();
1994 List<SequenceGroup> groups = alignment.getGroups();
1997 for (SequenceGroup sg : groups)
1999 if (sg.getEndRes() > alWidth)
2001 sg.setEndRes(alWidth - 1);
2006 if (selectionGroup != null && selectionGroup.getEndRes() > alWidth)
2008 selectionGroup.setEndRes(alWidth - 1);
2011 updateAllColourSchemes();
2012 calculator.restartWorkers();
2016 * reset scope and do calculations for all applied colourschemes on alignment
2018 void updateAllColourSchemes()
2020 ResidueShaderI rs = residueShading;
2023 rs.alignmentChanged(alignment, hiddenRepSequences);
2025 rs.setConsensus(hconsensus);
2026 if (rs.conservationApplied())
2028 rs.setConservation(Conservation.calculateConservation("All",
2029 alignment.getSequences(), 0, alignment.getWidth(), false,
2030 getConsPercGaps(), false));
2034 for (SequenceGroup sg : alignment.getGroups())
2038 sg.cs.alignmentChanged(sg, hiddenRepSequences);
2040 sg.recalcConservation();
2044 protected void initAutoAnnotation()
2046 // TODO: add menu option action that nulls or creates consensus object
2047 // depending on if the user wants to see the annotation or not in a
2048 // specific alignment
2050 if (hconsensus == null && !isDataset)
2052 if (!alignment.isNucleotide())
2061 consensus = new AlignmentAnnotation("Consensus",
2062 MessageManager.getString("label.consensus_descr"),
2063 new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH);
2064 initConsensus(consensus);
2068 initComplementConsensus();
2073 * If this is a protein alignment and there are mappings to cDNA, adds the
2074 * cDNA consensus annotation and returns true, else returns false.
2076 public boolean initComplementConsensus()
2078 if (!alignment.isNucleotide())
2080 final List<AlignedCodonFrame> codonMappings = alignment
2082 if (codonMappings != null && !codonMappings.isEmpty())
2084 boolean doConsensus = false;
2085 for (AlignedCodonFrame mapping : codonMappings)
2087 // TODO hold mapping type e.g. dna-to-protein in AlignedCodonFrame?
2088 MapList[] mapLists = mapping.getdnaToProt();
2089 // mapLists can be empty if project load has not finished resolving
2091 if (mapLists.length > 0 && mapLists[0].getFromRatio() == 3)
2099 complementConsensus = new AlignmentAnnotation("cDNA Consensus",
2101 .getString("label.complement_consensus_descr"),
2102 new Annotation[1], 0f, 100f,
2103 AlignmentAnnotation.BAR_GRAPH);
2104 initConsensus(complementConsensus);
2112 private void initConsensus(AlignmentAnnotation aa)
2115 aa.autoCalculated = true;
2119 alignment.addAnnotation(aa);
2123 // these should be extracted from the view model - style and settings for
2124 // derived annotation
2125 private void initGapCounts()
2129 gapcounts = new AlignmentAnnotation("Occupancy",
2130 MessageManager.getString("label.occupancy_descr"),
2131 new Annotation[1], 0f, alignment.getHeight(),
2132 AlignmentAnnotation.BAR_GRAPH);
2133 gapcounts.hasText = true;
2134 gapcounts.autoCalculated = true;
2135 gapcounts.scaleColLabel = true;
2136 gapcounts.graph = AlignmentAnnotation.BAR_GRAPH;
2138 alignment.addAnnotation(gapcounts);
2142 private void initConservation()
2144 if (showConservation)
2146 if (conservation == null)
2148 conservation = new AlignmentAnnotation("Conservation",
2149 MessageManager.formatMessage("label.conservation_descr",
2151 new Annotation[1], 0f, 11f, AlignmentAnnotation.BAR_GRAPH);
2152 conservation.hasText = true;
2153 conservation.autoCalculated = true;
2154 alignment.addAnnotation(conservation);
2159 private void initQuality()
2163 if (quality == null)
2165 quality = new AlignmentAnnotation("Quality",
2166 MessageManager.getString("label.quality_descr"),
2167 new Annotation[1], 0f, 11f, AlignmentAnnotation.BAR_GRAPH);
2168 quality.hasText = true;
2169 quality.autoCalculated = true;
2170 alignment.addAnnotation(quality);
2175 private void initRNAStructure()
2177 if (alignment.hasRNAStructure() && strucConsensus == null)
2179 strucConsensus = new AlignmentAnnotation("StrucConsensus",
2180 MessageManager.getString("label.strucconsensus_descr"),
2181 new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH);
2182 strucConsensus.hasText = true;
2183 strucConsensus.autoCalculated = true;
2187 alignment.addAnnotation(strucConsensus);
2195 * @see jalview.api.AlignViewportI#calcPanelHeight()
2198 public int calcPanelHeight()
2200 // setHeight of panels
2201 AlignmentAnnotation[] anns = getAlignment().getAlignmentAnnotation();
2203 int charHeight = getCharHeight();
2206 BitSet graphgrp = new BitSet();
2207 for (AlignmentAnnotation aa : anns)
2211 System.err.println("Null annotation row: ignoring.");
2218 if (aa.graphGroup > -1)
2220 if (graphgrp.get(aa.graphGroup))
2226 graphgrp.set(aa.graphGroup);
2233 aa.height += charHeight;
2243 aa.height += aa.graphHeight;
2251 height += aa.height;
2263 public void updateGroupAnnotationSettings(boolean applyGlobalSettings,
2264 boolean preserveNewGroupSettings)
2266 boolean updateCalcs = false;
2267 boolean conv = isShowGroupConservation();
2268 boolean cons = isShowGroupConsensus();
2269 boolean showprf = isShowSequenceLogo();
2270 boolean showConsHist = isShowConsensusHistogram();
2271 boolean normLogo = isNormaliseSequenceLogo();
2272 boolean showHMMPrf = isShowHMMSequenceLogo();
2273 boolean showInfoHist = isShowInformationHistogram();
2274 boolean normHMMLogo = isNormaliseHMMSequenceLogo();
2277 * TODO reorder the annotation rows according to group/sequence ordering on
2280 boolean sortg = true;
2282 // remove old automatic annotation
2283 // add any new annotation
2285 // intersect alignment annotation with alignment groups
2287 AlignmentAnnotation[] aan = alignment.getAlignmentAnnotation();
2288 List<SequenceGroup> oldrfs = new ArrayList<>();
2291 for (int an = 0; an < aan.length; an++)
2293 if (aan[an].autoCalculated && aan[an].groupRef != null)
2295 oldrfs.add(aan[an].groupRef);
2296 alignment.deleteAnnotation(aan[an], false);
2300 if (alignment.getGroups() != null)
2302 for (SequenceGroup sg : alignment.getGroups())
2304 updateCalcs = false;
2305 if (applyGlobalSettings
2306 || (!preserveNewGroupSettings && !oldrfs.contains(sg)))
2308 // set defaults for this group's conservation/consensus
2309 sg.setshowSequenceLogo(showprf);
2310 sg.setShowConsensusHistogram(showConsHist);
2311 sg.setNormaliseSequenceLogo(normLogo);
2312 sg.setShowHMMSequenceLogo(showHMMPrf);
2313 sg.setShowInformationHistogram(showInfoHist);
2314 sg.setNormaliseHMMSequenceLogo(normHMMLogo);
2319 alignment.addAnnotation(sg.getConservationRow(), 0);
2324 alignment.addAnnotation(sg.getConsensus(), 0);
2326 // refresh the annotation rows
2329 sg.recalcConservation();
2337 public boolean isDisplayReferenceSeq()
2339 return alignment.hasSeqrep() && viewStyle.isDisplayReferenceSeq();
2343 public void setDisplayReferenceSeq(boolean displayReferenceSeq)
2345 viewStyle.setDisplayReferenceSeq(displayReferenceSeq);
2349 public boolean isColourByReferenceSeq()
2351 return alignment.hasSeqrep() && viewStyle.isColourByReferenceSeq();
2355 public Color getSequenceColour(SequenceI seq)
2357 Color sqc = sequenceColours.get(seq);
2358 return (sqc == null ? Color.white : sqc);
2362 public void setSequenceColour(SequenceI seq, Color col)
2366 sequenceColours.remove(seq);
2370 sequenceColours.put(seq, col);
2375 public void updateSequenceIdColours()
2377 for (SequenceGroup sg : alignment.getGroups())
2379 if (sg.idColour != null)
2381 for (SequenceI s : sg.getSequences(getHiddenRepSequences()))
2383 sequenceColours.put(s, sg.idColour);
2390 public void clearSequenceColours()
2392 sequenceColours.clear();
2396 public AlignViewportI getCodingComplement()
2398 return this.codingComplement;
2402 * Set this as the (cDna/protein) complement of the given viewport. Also
2403 * ensures the reverse relationship is set on the given viewport.
2406 public void setCodingComplement(AlignViewportI av)
2410 System.err.println("Ignoring recursive setCodingComplement request");
2414 this.codingComplement = av;
2415 // avoid infinite recursion!
2416 if (av.getCodingComplement() != this)
2418 av.setCodingComplement(this);
2424 public boolean isNucleotide()
2426 return getAlignment() == null ? false : getAlignment().isNucleotide();
2430 public FeaturesDisplayedI getFeaturesDisplayed()
2432 return featuresDisplayed;
2436 public void setFeaturesDisplayed(FeaturesDisplayedI featuresDisplayedI)
2438 featuresDisplayed = featuresDisplayedI;
2442 public boolean areFeaturesDisplayed()
2444 return featuresDisplayed != null
2445 && featuresDisplayed.getRegisteredFeaturesCount() > 0;
2452 * features are displayed if true
2455 public void setShowSequenceFeatures(boolean b)
2457 viewStyle.setShowSequenceFeatures(b);
2461 public boolean isShowSequenceFeatures()
2463 return viewStyle.isShowSequenceFeatures();
2467 public void setShowSequenceFeaturesHeight(boolean selected)
2469 viewStyle.setShowSequenceFeaturesHeight(selected);
2473 public boolean isShowSequenceFeaturesHeight()
2475 return viewStyle.isShowSequenceFeaturesHeight();
2479 public void setShowAnnotation(boolean b)
2481 viewStyle.setShowAnnotation(b);
2485 public boolean isShowAnnotation()
2487 return viewStyle.isShowAnnotation();
2491 public boolean isRightAlignIds()
2493 return viewStyle.isRightAlignIds();
2497 public void setRightAlignIds(boolean rightAlignIds)
2499 viewStyle.setRightAlignIds(rightAlignIds);
2503 public boolean getConservationSelected()
2505 return viewStyle.getConservationSelected();
2509 public void setShowBoxes(boolean state)
2511 viewStyle.setShowBoxes(state);
2516 * @see jalview.api.ViewStyleI#getTextColour()
2519 public Color getTextColour()
2521 return viewStyle.getTextColour();
2526 * @see jalview.api.ViewStyleI#getTextColour2()
2529 public Color getTextColour2()
2531 return viewStyle.getTextColour2();
2536 * @see jalview.api.ViewStyleI#getThresholdTextColour()
2539 public int getThresholdTextColour()
2541 return viewStyle.getThresholdTextColour();
2546 * @see jalview.api.ViewStyleI#isConservationColourSelected()
2549 public boolean isConservationColourSelected()
2551 return viewStyle.isConservationColourSelected();
2556 * @see jalview.api.ViewStyleI#isRenderGaps()
2559 public boolean isRenderGaps()
2561 return viewStyle.isRenderGaps();
2566 * @see jalview.api.ViewStyleI#isShowColourText()
2569 public boolean isShowColourText()
2571 return viewStyle.isShowColourText();
2575 * @param conservationColourSelected
2576 * @see jalview.api.ViewStyleI#setConservationColourSelected(boolean)
2579 public void setConservationColourSelected(
2580 boolean conservationColourSelected)
2582 viewStyle.setConservationColourSelected(conservationColourSelected);
2586 * @param showColourText
2587 * @see jalview.api.ViewStyleI#setShowColourText(boolean)
2590 public void setShowColourText(boolean showColourText)
2592 viewStyle.setShowColourText(showColourText);
2597 * @see jalview.api.ViewStyleI#setTextColour(java.awt.Color)
2600 public void setTextColour(Color textColour)
2602 viewStyle.setTextColour(textColour);
2606 * @param thresholdTextColour
2607 * @see jalview.api.ViewStyleI#setThresholdTextColour(int)
2610 public void setThresholdTextColour(int thresholdTextColour)
2612 viewStyle.setThresholdTextColour(thresholdTextColour);
2616 * @param textColour2
2617 * @see jalview.api.ViewStyleI#setTextColour2(java.awt.Color)
2620 public void setTextColour2(Color textColour2)
2622 viewStyle.setTextColour2(textColour2);
2626 public ViewStyleI getViewStyle()
2628 return new ViewStyle(viewStyle);
2632 public void setViewStyle(ViewStyleI settingsForView)
2634 viewStyle = new ViewStyle(settingsForView);
2635 if (residueShading != null)
2637 residueShading.setConservationApplied(
2638 settingsForView.isConservationColourSelected());
2643 public boolean sameStyle(ViewStyleI them)
2645 return viewStyle.sameStyle(them);
2650 * @see jalview.api.ViewStyleI#getIdWidth()
2653 public int getIdWidth()
2655 return viewStyle.getIdWidth();
2660 * @see jalview.api.ViewStyleI#setIdWidth(int)
2663 public void setIdWidth(int i)
2665 viewStyle.setIdWidth(i);
2670 * @see jalview.api.ViewStyleI#isCentreColumnLabels()
2673 public boolean isCentreColumnLabels()
2675 return viewStyle.isCentreColumnLabels();
2679 * @param centreColumnLabels
2680 * @see jalview.api.ViewStyleI#setCentreColumnLabels(boolean)
2683 public void setCentreColumnLabels(boolean centreColumnLabels)
2685 viewStyle.setCentreColumnLabels(centreColumnLabels);
2690 * @see jalview.api.ViewStyleI#setShowDBRefs(boolean)
2693 public void setShowDBRefs(boolean showdbrefs)
2695 viewStyle.setShowDBRefs(showdbrefs);
2700 * @see jalview.api.ViewStyleI#isShowDBRefs()
2703 public boolean isShowDBRefs()
2705 return viewStyle.isShowDBRefs();
2710 * @see jalview.api.ViewStyleI#isShowNPFeats()
2713 public boolean isShowNPFeats()
2715 return viewStyle.isShowNPFeats();
2719 * @param shownpfeats
2720 * @see jalview.api.ViewStyleI#setShowNPFeats(boolean)
2723 public void setShowNPFeats(boolean shownpfeats)
2725 viewStyle.setShowNPFeats(shownpfeats);
2728 public abstract StructureSelectionManager getStructureSelectionManager();
2731 * Add one command to the command history list.
2735 public void addToHistoryList(CommandI command)
2737 if (this.historyList != null)
2739 this.historyList.push(command);
2740 broadcastCommand(command, false);
2744 protected void broadcastCommand(CommandI command, boolean undo)
2746 getStructureSelectionManager().commandPerformed(command, undo,
2751 * Add one command to the command redo list.
2755 public void addToRedoList(CommandI command)
2757 if (this.redoList != null)
2759 this.redoList.push(command);
2761 broadcastCommand(command, true);
2765 * Clear the command redo list.
2767 public void clearRedoList()
2769 if (this.redoList != null)
2771 this.redoList.clear();
2775 public void setHistoryList(Deque<CommandI> list)
2777 this.historyList = list;
2780 public Deque<CommandI> getHistoryList()
2782 return this.historyList;
2785 public void setRedoList(Deque<CommandI> list)
2787 this.redoList = list;
2790 public Deque<CommandI> getRedoList()
2792 return this.redoList;
2796 public VamsasSource getVamsasSource()
2801 public SequenceAnnotationOrder getSortAnnotationsBy()
2803 return sortAnnotationsBy;
2806 public void setSortAnnotationsBy(
2807 SequenceAnnotationOrder sortAnnotationsBy)
2809 this.sortAnnotationsBy = sortAnnotationsBy;
2812 public boolean isShowAutocalculatedAbove()
2814 return showAutocalculatedAbove;
2817 public void setShowAutocalculatedAbove(boolean showAutocalculatedAbove)
2819 this.showAutocalculatedAbove = showAutocalculatedAbove;
2823 public boolean isScaleProteinAsCdna()
2825 return viewStyle.isScaleProteinAsCdna();
2829 public void setScaleProteinAsCdna(boolean b)
2831 viewStyle.setScaleProteinAsCdna(b);
2835 public boolean isProteinFontAsCdna()
2837 return viewStyle.isProteinFontAsCdna();
2841 public void setProteinFontAsCdna(boolean b)
2843 viewStyle.setProteinFontAsCdna(b);
2847 * @return true if view should scroll to show the highlighted region of a
2852 public final boolean isFollowHighlight()
2854 return followHighlight;
2858 public final void setFollowHighlight(boolean b)
2860 this.followHighlight = b;
2864 public ViewportRanges getRanges()
2870 * Helper method to populate the SearchResults with the location in the
2871 * complementary alignment to scroll to, in order to match this one.
2874 * the SearchResults to add to
2875 * @return the offset (below top of visible region) of the matched sequence
2877 protected int findComplementScrollTarget(SearchResultsI sr)
2879 final AlignViewportI complement = getCodingComplement();
2880 if (complement == null || !complement.isFollowHighlight())
2884 boolean iAmProtein = !getAlignment().isNucleotide();
2885 AlignmentI proteinAlignment = iAmProtein ? getAlignment()
2886 : complement.getAlignment();
2887 if (proteinAlignment == null)
2891 final List<AlignedCodonFrame> mappings = proteinAlignment
2895 * Heuristic: find the first mapped sequence (if any) with a non-gapped
2896 * residue in the middle column of the visible region. Scroll the
2897 * complementary alignment to line up the corresponding residue.
2900 SequenceI sequence = null;
2903 * locate 'middle' column (true middle if an odd number visible, left of
2904 * middle if an even number visible)
2906 int middleColumn = ranges.getStartRes()
2907 + (ranges.getEndRes() - ranges.getStartRes()) / 2;
2908 final HiddenSequences hiddenSequences = getAlignment()
2909 .getHiddenSequences();
2912 * searching to the bottom of the alignment gives smoother scrolling across
2913 * all gapped visible regions
2915 int lastSeq = alignment.getHeight() - 1;
2916 List<AlignedCodonFrame> seqMappings = null;
2917 for (int seqNo = ranges
2918 .getStartSeq(); seqNo <= lastSeq; seqNo++, seqOffset++)
2920 sequence = getAlignment().getSequenceAt(seqNo);
2921 if (hiddenSequences != null && hiddenSequences.isHidden(sequence))
2925 if (Comparison.isGap(sequence.getCharAt(middleColumn)))
2929 seqMappings = MappingUtils.findMappingsForSequenceAndOthers(sequence,
2931 getCodingComplement().getAlignment().getSequences());
2932 if (!seqMappings.isEmpty())
2938 if (sequence == null || seqMappings == null || seqMappings.isEmpty())
2941 * No ungapped mapped sequence in middle column - do nothing
2945 MappingUtils.addSearchResults(sr, sequence,
2946 sequence.findPosition(middleColumn), seqMappings);
2951 * synthesize a column selection if none exists so it covers the given
2952 * selection group. if wholewidth is false, no column selection is made if the
2953 * selection group covers the whole alignment width.
2958 public void expandColSelection(SequenceGroup sg, boolean wholewidth)
2961 if (sg != null && (sgs = sg.getStartRes()) >= 0
2962 && sg.getStartRes() <= (sge = sg.getEndRes())
2963 && !this.hasSelectedColumns())
2965 if (!wholewidth && alignment.getWidth() == (1 + sge - sgs))
2972 colSel = new ColumnSelection();
2974 for (int cspos = sg.getStartRes(); cspos <= sg.getEndRes(); cspos++)
2976 colSel.addElement(cspos);
2982 * hold status of current selection group - defined on alignment or not.
2984 private boolean selectionIsDefinedGroup = false;
2987 public boolean isSelectionDefinedGroup()
2989 if (selectionGroup == null)
2993 if (isSelectionGroupChanged(true))
2995 selectionIsDefinedGroup = false;
2996 List<SequenceGroup> gps = alignment.getGroups();
2997 if (gps == null || gps.size() == 0)
2999 selectionIsDefinedGroup = false;
3003 selectionIsDefinedGroup = gps.contains(selectionGroup);
3006 return selectionGroup.isDefined() || selectionIsDefinedGroup;
3010 * null, or currently highlighted results on this view
3012 private SearchResultsI searchResults = null;
3014 protected TreeModel currentTree = null;
3017 public boolean hasSearchResults()
3019 return searchResults != null;
3023 public void setSearchResults(SearchResultsI results)
3025 searchResults = results;
3029 public SearchResultsI getSearchResults()
3031 return searchResults;
3035 * get the consensus sequence as displayed under the PID consensus annotation
3038 * @return consensus sequence as a new sequence object
3040 public SequenceI getConsensusSeq()
3042 if (consensus == null)
3044 updateConsensus(null);
3046 if (consensus == null)
3050 StringBuffer seqs = new StringBuffer();
3051 for (int i = 0; i < consensus.annotations.length; i++)
3053 Annotation annotation = consensus.annotations[i];
3054 if (annotation != null)
3056 String description = annotation.description;
3057 if (description != null && description.startsWith("["))
3059 // consensus is a tie - just pick the first one
3060 seqs.append(description.charAt(1));
3064 seqs.append(annotation.displayCharacter);
3069 SequenceI sq = new Sequence("Consensus", seqs.toString());
3070 sq.setDescription("Percentage Identity Consensus "
3071 + ((ignoreGapsInConsensusCalculation) ? " without gaps" : ""));
3075 public boolean hasReferenceAnnotation()
3077 AlignmentAnnotation[] annots = this.alignment.getAlignmentAnnotation();
3078 for (AlignmentAnnotation annot : annots)
3080 if ("RF".equals(annot.label) || annot.label.contains("Reference"))
3089 public void setCurrentTree(TreeModel tree)
3095 public TreeModel getCurrentTree()
3101 public boolean isNormaliseSequenceLogo()
3103 return normaliseSequenceLogo;
3106 public void setNormaliseSequenceLogo(boolean state)
3108 normaliseSequenceLogo = state;
3112 public boolean isNormaliseHMMSequenceLogo()
3114 return hmmNormaliseSequenceLogo;
3117 public void setNormaliseHMMSequenceLogo(boolean state)
3119 hmmNormaliseSequenceLogo = state;
3123 * flag set to indicate if structure views might be out of sync with sequences
3127 private boolean needToUpdateStructureViews = false;
3130 public boolean isUpdateStructures()
3132 return needToUpdateStructureViews;
3136 public void setUpdateStructures(boolean update)
3138 needToUpdateStructureViews = update;
3142 public boolean needToUpdateStructureViews()
3144 boolean update = needToUpdateStructureViews;
3145 needToUpdateStructureViews = false;
3150 public void addSequenceGroup(SequenceGroup sequenceGroup)
3152 alignment.addGroup(sequenceGroup);
3154 Color col = sequenceGroup.idColour;
3157 col = col.brighter();
3159 for (SequenceI sq : sequenceGroup.getSequences())
3161 setSequenceColour(sq, col);
3165 if (codingComplement != null)
3167 SequenceGroup mappedGroup = MappingUtils
3168 .mapSequenceGroup(sequenceGroup, this, codingComplement);
3169 if (mappedGroup.getSequences().size() > 0)
3171 codingComplement.getAlignment().addGroup(mappedGroup);
3175 for (SequenceI seq : mappedGroup.getSequences())
3177 codingComplement.setSequenceColour(seq, col);
3181 // propagate the structure view update flag according to our own setting
3182 codingComplement.setUpdateStructures(needToUpdateStructureViews);
3187 * Filters out sequences with an eValue higher than the specified value. The
3188 * filtered sequences are hidden or deleted. Sequences with no eValues are also
3194 public void filterByEvalue(double eValue)
3196 for (SequenceI seq : alignment.getSequencesArray())
3198 if ((seq.getAnnotation("Search Scores") == null
3199 || seq.getAnnotation("Search Scores")[0].getEValue() > eValue)
3200 && seq.getHMM() == null)
3202 hideSequence(new SequenceI[] { seq });
3208 * Filters out sequences with an score lower than the specified value. The
3209 * filtered sequences are hidden or deleted.
3214 public void filterByScore(double score)
3216 for (SequenceI seq : alignment.getSequencesArray())
3218 if ((seq.getAnnotation("Search Scores") == null
3219 || seq.getAnnotation("Search Scores")[0]
3220 .getBitScore() < score)
3221 && seq.getHMM() == null)
3223 hideSequence(new SequenceI[] { seq });