import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
import jalview.analysis.Conservation;
+import jalview.analysis.TreeModel;
import jalview.api.AlignCalcManagerI;
+import jalview.api.AlignExportSettingsI;
import jalview.api.AlignViewportI;
import jalview.api.AlignmentViewPanel;
import jalview.api.FeaturesDisplayedI;
import jalview.commands.CommandI;
import jalview.datamodel.AlignedCodonFrame;
import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentExportData;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.AlignmentView;
import jalview.datamodel.Annotation;
-import jalview.datamodel.CigarArray;
import jalview.datamodel.ColumnSelection;
import jalview.datamodel.HiddenColumns;
import jalview.datamodel.HiddenSequences;
-import jalview.datamodel.ProfileI;
-import jalview.datamodel.Profiles;
import jalview.datamodel.ProfilesI;
import jalview.datamodel.SearchResultsI;
import jalview.datamodel.Sequence;
import java.util.Deque;
import java.util.HashMap;
import java.util.Hashtable;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
public abstract class AlignmentViewport
implements AlignViewportI, CommandListener, VamsasSource
{
- final protected ViewportRanges ranges;
+ protected ViewportRanges ranges;
protected ViewStyleI viewStyle = new ViewStyle();
protected Deque<CommandI> redoList = new ArrayDeque<>();
-
/**
* alignment displayed in the viewport. Please use get/setter
*/
protected AlignmentI alignment;
+
+ /*
+ * probably unused indicator that view is of a dataset rather than an
+ * alignment
+ */
+
+ protected boolean ignoreBelowBackGroundFrequencyCalculation = false;
+
+ protected boolean infoLetterHeight = false;
+
+ protected AlignmentAnnotation occupancy;
+
+ /**
+ * results of alignment consensus analysis for visible portion of view
+ */
+ protected ProfilesI consensusProfiles;
+
+ /**
+ * HMM profile for the alignment
+ */
+ protected ProfilesI hmmProfiles;
public AlignmentViewport(AlignmentI al)
{
public void setWrapAlignment(boolean state)
{
viewStyle.setWrapAlignment(state);
+ ranges.setWrappedMode(state);
}
/**
* alignment
*/
protected boolean isDataset = false;
-
+
public void setDataset(boolean b)
{
isDataset = b;
public boolean autoCalculateConsensus = true;
- public boolean autoCalculateInformation = true;
-
protected boolean autoCalculateStrucConsensus = true;
protected boolean ignoreGapsInConsensusCalculation = false;
- protected boolean ignoreBelowBackGroundFrequencyCalculation = false;
-
protected ResidueShaderI residueShading = new ResidueShader();
-
+
@Override
public void setGlobalColourScheme(ColourSchemeI cs)
{
{
residueShading.setConservation(hconservation);
}
+ /*
+ * reset conservation flag in case just set to false if
+ * Conservation was null (calculation still in progress)
+ */
+ residueShading.setConservationApplied(getConservationSelected());
residueShading.alignmentChanged(alignment, hiddenRepSequences);
}
* retain any colour thresholds per group while
* changing choice of colour scheme (JAL-2386)
*/
- sg.setColourScheme(cs);
+ sg.setColourScheme(
+ cs == null ? null : cs.getInstance(this, sg));
if (cs != null)
{
sg.getGroupColourScheme().alignmentChanged(sg,
{
return residueShading;
}
-
+
protected AlignmentAnnotation consensus;
protected AlignmentAnnotation complementConsensus;
protected AlignmentAnnotation[] groupConservation;
- protected List<AlignmentAnnotation> groupInformation = new ArrayList<>();
-
- protected List<AlignmentAnnotation> information = new ArrayList<>();
-
/**
* results of alignment consensus analysis for visible portion of view
*/
protected ProfilesI hconsensus = null;
- protected List<ProfilesI> hinformation = new ArrayList<>();
-
/**
* results of cDNA complement consensus visible portion of view
*/
- protected Hashtable[] hcomplementConsensus = null;
+ protected Hashtable<String, Object>[] hcomplementConsensus = null;
/**
* results of secondary structure base pair consensus for visible portion of
* view
*/
- protected Hashtable[] hStrucConsensus = null;
+ protected Hashtable<String, Object>[] hStrucConsensus = null;
protected Conservation hconservation = null;
-
+
@Override
public void setConservation(Conservation cons)
{
}
@Override
- public void setComplementConsensusHash(Hashtable[] hconsensus)
+ public void setComplementConsensusHash(
+ Hashtable<String, Object>[] hconsensus)
{
this.hcomplementConsensus = hconsensus;
}
}
@Override
- public void setSequenceInformationHashes(List<ProfilesI> info)
+ public void setHmmProfiles(ProfilesI info)
{
- hinformation = info;
+ hmmProfiles = info;
}
@Override
- public void setSequenceInformationHash(ProfilesI info, int index)
+ public ProfilesI getHmmProfiles()
{
- hinformation.set(index, info);
+ return hmmProfiles;
}
@Override
- public List<ProfilesI> getSequenceInformationHashes()
- {
- return hinformation;
- }
-
- @Override
- public ProfilesI getSequenceInformationHash(int index)
- {
- return hinformation.get(index);
- }
-
- @Override
- public Hashtable[] getComplementConsensusHash()
+ public Hashtable<String, Object>[] getComplementConsensusHash()
{
return hcomplementConsensus;
}
@Override
- public Hashtable[] getRnaStructureConsensusHash()
+ public Hashtable<String, Object>[] getRnaStructureConsensusHash()
{
return hStrucConsensus;
}
@Override
- public void setRnaStructureConsensusHash(Hashtable[] hStrucConsensus)
+ public void setRnaStructureConsensusHash(
+ Hashtable<String, Object>[] hStrucConsensus)
{
this.hStrucConsensus = hStrucConsensus;
}
@Override
- public List<AlignmentAnnotation> getInformationAnnotations()
- {
- return information;
- }
-
- @Override
- public AlignmentAnnotation getInformationAnnotation(int index)
- {
- return information.get(index);
- }
-
- @Override
public AlignmentAnnotation getAlignmentGapAnnotation()
{
return gapcounts;
}
}
- /**
- * trigger update of information annotation
- */
@Override
- public void updateInformation(final AlignmentViewPanel ap)
+ public void initInformationWorker(final AlignmentViewPanel ap)
{
if (calculator
.getRegisteredWorkersOfClass(InformationThread.class) == null)
{
calculator.registerWorker(new InformationThread(this, ap));
}
-
}
// --------START Structure Conservation
strucConsensus = null;
conservation = null;
quality = null;
+ consensusProfiles = null;
groupConsensus = null;
groupConservation = null;
hconsensus = null;
+ hconservation = null;
hcomplementConsensus = null;
- // colour scheme may hold reference to consensus
- residueShading = null;
- // TODO remove listeners from changeSupport?
+ gapcounts = null;
+ calculator = null;
+ residueShading = null; // may hold a reference to Consensus
changeSupport = null;
+ ranges = null;
+ currentTree = null;
+ selectionGroup = null;
setAlignment(null);
}
/**
* should hmm profile be rendered by default
*/
- protected boolean showHMMSequenceLogo = false;
+ protected boolean hmmShowSequenceLogo = false;
/**
* should hmm profile be rendered normalised to row height
*/
- protected boolean normaliseHMMSequenceLogo = false;
+ protected boolean hmmNormaliseSequenceLogo = false;
/**
* should information histograms be rendered by default
*/
- protected boolean showInformationHistogram = true;
+ protected boolean hmmShowHistogram = true;
/**
* @return the showConsensusProfile
@Override
public boolean isShowHMMSequenceLogo()
{
- return showHMMSequenceLogo;
+ return hmmShowSequenceLogo;
}
/**
public void setShowHMMSequenceLogo(boolean showHMMSequenceLogo)
{
- if (showHMMSequenceLogo != this.showHMMSequenceLogo)
+ if (showHMMSequenceLogo != this.hmmShowSequenceLogo)
{
- this.showHMMSequenceLogo = showHMMSequenceLogo;
- calculator.updateAnnotationFor(InformationThread.class);
+ this.hmmShowSequenceLogo = showHMMSequenceLogo;
+ // TODO: updateAnnotation if description (tooltip) will show
+ // profile in place of information content?
+ // calculator.updateAnnotationFor(InformationThread.class);
}
- this.showHMMSequenceLogo = showHMMSequenceLogo;
+ this.hmmShowSequenceLogo = showHMMSequenceLogo;
}
/**
/**
* @param showInformationHistogram
- * the showInformationHistogram to set
*/
public void setShowInformationHistogram(boolean showInformationHistogram)
{
- this.showInformationHistogram = showInformationHistogram;
+ this.hmmShowHistogram = showInformationHistogram;
}
/**
@Override
public boolean isShowInformationHistogram()
{
- return this.showInformationHistogram;
+ return this.hmmShowHistogram;
}
/**
@Override
public boolean hasHiddenColumns()
{
- return colSel != null
+ return alignment.getHiddenColumns() != null
&& alignment.getHiddenColumns().hasHiddenColumns();
}
ignoreGapsInConsensusCalculation);
}
}
-
}
public void setIgnoreBelowBackground(boolean b, AlignmentViewPanel ap)
{
ignoreBelowBackGroundFrequencyCalculation = b;
- if (ap != null)
- {
- updateInformation(ap);
- }
+ }
+ public void setInfoLetterHeight(boolean b, AlignmentViewPanel ap)
+ {
+ infoLetterHeight = b;
}
private long sgrouphash = -1, colselhash = -1;
return ignoreBelowBackGroundFrequencyCalculation;
}
+ @Override
+ public boolean isInfoLetterHeight()
+ {
+ return infoLetterHeight;
+ }
+
// property change stuff
// JBPNote Prolly only need this in the applet version.
private PropertyChangeSupport changeSupport = new PropertyChangeSupport(
public void removePropertyChangeListener(
java.beans.PropertyChangeListener listener)
{
- changeSupport.removePropertyChangeListener(listener);
+ if (changeSupport != null)
+ {
+ changeSupport.removePropertyChangeListener(listener);
+ }
}
/**
// common hide/show seq stuff
public void showAllHiddenSeqs()
{
+ int startSeq = ranges.getStartSeq();
+ int endSeq = ranges.getEndSeq();
+
if (alignment.getHiddenSequences().getSize() > 0)
{
if (selectionGroup == null)
hiddenRepSequences = null;
+ ranges.setStartEndSeq(startSeq, endSeq + tmp.size());
+
firePropertyChange("alignment", null, alignment.getSequences());
// used to set hasHiddenRows/hiddenRepSequences here, after the property
// changed event
public void showSequence(int index)
{
+ int startSeq = ranges.getStartSeq();
+ int endSeq = ranges.getEndSeq();
+
List<SequenceI> tmp = alignment.getHiddenSequences().showSequence(index,
hiddenRepSequences);
if (tmp.size() > 0)
selectionGroup.addSequence(seq, false);
setSequenceAnnotationsVisible(seq, true);
}
+
+ ranges.setStartEndSeq(startSeq, endSeq + tmp.size());
+
firePropertyChange("alignment", null, alignment.getSequences());
sendSelection();
}
public void hideSequence(SequenceI[] seq)
{
+ /*
+ * cache offset to first visible sequence
+ */
+ int startSeq = ranges.getStartSeq();
+
if (seq != null)
{
for (int i = 0; i < seq.length; i++)
alignment.getHiddenSequences().hideSequence(seq[i]);
setSequenceAnnotationsVisible(seq[i], false);
}
+ ranges.setStartSeq(startSeq);
firePropertyChange("alignment", null, alignment.getSequences());
}
}
public void invertColumnSelection()
{
colSel.invertColumnSelection(0, alignment.getWidth(), alignment);
+ isColSelChanged(true);
}
@Override
}
@Override
- public CigarArray getViewAsCigars(boolean selectedRegionOnly)
- {
- return new CigarArray(alignment, alignment.getHiddenColumns(),
- (selectedRegionOnly ? selectionGroup : null));
- }
-
- @Override
public jalview.datamodel.AlignmentView getAlignmentView(
boolean selectedOnly)
{
boolean selectedOnly, boolean markGroups)
{
return new AlignmentView(alignment, alignment.getHiddenColumns(),
- selectionGroup, alignment.getHiddenColumns() != null
+ selectionGroup,
+ alignment.getHiddenColumns() != null
&& alignment.getHiddenColumns().hasHiddenColumns(),
selectedOnly, markGroups);
}
if (alignment.getHiddenColumns() != null
&& alignment.getHiddenColumns().hasHiddenColumns())
{
- selection = alignment.getHiddenColumns()
- .getVisibleSequenceStrings(start, end, seqs);
+ for (i = 0; i < iSize; i++)
+ {
+ Iterator<int[]> blocks = alignment.getHiddenColumns()
+ .getVisContigsIterator(start, end + 1, false);
+ selection[i] = seqs[i].getSequenceStringFromIterator(blocks);
+ }
}
else
{
{
if (start == 0)
{
- start = hidden.adjustForHiddenColumns(start);
+ start = hidden.visibleToAbsoluteColumn(start);
}
- end = hidden.getHiddenBoundaryRight(start);
+ end = hidden.getNextHiddenBoundary(false, start);
if (start == end)
{
end = max;
if (hidden != null && hidden.hasHiddenColumns())
{
- start = hidden.adjustForHiddenColumns(end);
- start = hidden.getHiddenBoundaryLeft(start) + 1;
+ start = hidden.visibleToAbsoluteColumn(end);
+ start = hidden.getNextHiddenBoundary(true, start) + 1;
}
} while (end < max);
- int[][] startEnd = new int[regions.size()][2];
+ // int[][] startEnd = new int[regions.size()][2];
return regions;
}
AlignmentAnnotation clone = new AlignmentAnnotation(annot);
if (selectedOnly && selectionGroup != null)
{
- alignment.getHiddenColumns().makeVisibleAnnotation(
+ clone.makeVisibleAnnotation(
selectionGroup.getStartRes(), selectionGroup.getEndRes(),
- clone);
+ alignment.getHiddenColumns());
}
else
{
- alignment.getHiddenColumns().makeVisibleAnnotation(clone);
+ clone.makeVisibleAnnotation(alignment.getHiddenColumns());
}
ala.add(clone);
}
{
updateStrucConsensus(ap);
}
- updateInformation(ap);
-
- List<SequenceI> hmmSequences;
- hmmSequences = alignment.getHMMConsensusSequences(false);
-
- for (SequenceI seq : hmmSequences)
- {
- seq.updateHMMMapping();
- }
// Reset endRes of groups if beyond alignment width
int alWidth = alignment.getWidth();
updateAllColourSchemes();
calculator.restartWorkers();
- // alignment.adjustSequenceAnnotations();
}
/**
}
}
- @Override
- public void initInformation()
- {
- for (SequenceI seq : alignment.getHMMConsensusSequences(false))
- {
- if (!seq.hasHMMAnnotation())
- {
- AlignmentAnnotation information;
- information = new AlignmentAnnotation(seq.getName(),
- MessageManager.getString("label.information_description"),
- new Annotation[1], 0f, 6.52f,
- AlignmentAnnotation.BAR_GRAPH);
- information.hasText = true;
- information.autoCalculated = true;
- information.hasText = true;
- information.autoCalculated = false;
- information.sequenceRef = seq;
- information.setCalcId("HMM annotation");
- this.information.add(information);
- hinformation.add(new Profiles(new ProfileI[1]));
- alignment.addAnnotation(information);
- seq.updateHMMMapping();
- seq.setHasInfo(true);
- seq.addAlignmentAnnotation(information);
- }
- }
-
- }
-
// these should be extracted from the view model - style and settings for
// derived annotation
private void initGapCounts()
* TODO reorder the annotation rows according to group/sequence ordering on
* alignment
*/
- boolean sortg = true;
+ // boolean sortg = true;
// remove old automatic annotation
// add any new annotation
sg.setshowSequenceLogo(showprf);
sg.setShowConsensusHistogram(showConsHist);
sg.setNormaliseSequenceLogo(normLogo);
- sg.setshowHMMSequenceLogo(showHMMPrf);
+ sg.setShowHMMSequenceLogo(showHMMPrf);
sg.setShowInformationHistogram(showInfoHist);
sg.setNormaliseHMMSequenceLogo(normHMMLogo);
}
public void clearSequenceColours()
{
sequenceColours.clear();
- };
+ }
@Override
public AlignViewportI getCodingComplement()
viewStyle.setProteinFontAsCdna(b);
}
+ @Override
+ public void setShowComplementFeatures(boolean b)
+ {
+ viewStyle.setShowComplementFeatures(b);
+ }
+
+ @Override
+ public boolean isShowComplementFeatures()
+ {
+ return viewStyle.isShowComplementFeatures();
+ }
+
+ @Override
+ public void setShowComplementFeaturesOnTop(boolean b)
+ {
+ viewStyle.setShowComplementFeaturesOnTop(b);
+ }
+
+ @Override
+ public boolean isShowComplementFeaturesOnTop()
+ {
+ return viewStyle.isShowComplementFeaturesOnTop();
+ }
+
/**
* @return true if view should scroll to show the highlighted region of a
* sequence
int lastSeq = alignment.getHeight() - 1;
List<AlignedCodonFrame> seqMappings = null;
for (int seqNo = ranges
- .getStartSeq(); seqNo < lastSeq; seqNo++, seqOffset++)
+ .getStartSeq(); seqNo <= lastSeq; seqNo++, seqOffset++)
{
sequence = getAlignment().getSequenceAt(seqNo);
if (hiddenSequences != null && hiddenSequences.isHidden(sequence))
*/
private SearchResultsI searchResults = null;
+ protected TreeModel currentTree = null;
+
@Override
public boolean hasSearchResults()
{
}
/**
- * Gets the selected hidden Markov model
+ * get the consensus sequence as displayed under the PID consensus annotation
+ * row.
*
- * @return
+ * @return consensus sequence as a new sequence object
*/
+ public SequenceI getConsensusSeq()
+ {
+ if (consensus == null)
+ {
+ updateConsensus(null);
+ }
+ if (consensus == null)
+ {
+ return null;
+ }
+ StringBuffer seqs = new StringBuffer();
+ for (int i = 0; i < consensus.annotations.length; i++)
+ {
+ Annotation annotation = consensus.annotations[i];
+ if (annotation != null)
+ {
+ String description = annotation.description;
+ if (description != null && description.startsWith("["))
+ {
+ // consensus is a tie - just pick the first one
+ seqs.append(description.charAt(1));
+ }
+ else
+ {
+ seqs.append(annotation.displayCharacter);
+ }
+ }
+ }
+
+ SequenceI sq = new Sequence("Consensus", seqs.toString());
+ sq.setDescription("Percentage Identity Consensus "
+ + ((ignoreGapsInConsensusCalculation) ? " without gaps" : ""));
+ return sq;
+ }
+
+ public boolean hasReferenceAnnotation()
+ {
+ AlignmentAnnotation[] annots = this.alignment.getAlignmentAnnotation();
+ for (AlignmentAnnotation annot : annots)
+ {
+ if ("RF".equals(annot.label) || annot.label.contains("Reference"))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void setCurrentTree(TreeModel tree)
+ {
+ currentTree = tree;
+ }
+
+ @Override
+ public TreeModel getCurrentTree()
+ {
+ return currentTree;
+ }
+
+ @Override
+ public AlignmentExportData getAlignExportData(AlignExportSettingsI options)
+ {
+ AlignmentI alignmentToExport = null;
+ String[] omitHidden = null;
+ alignmentToExport = null;
+
+ if (hasHiddenColumns() && !options.isExportHiddenColumns())
+ {
+ omitHidden = getViewAsString(false,
+ options.isExportHiddenSequences());
+ }
+
+ int[] alignmentStartEnd = new int[2];
+ if (hasHiddenRows() && options.isExportHiddenSequences())
+ {
+ alignmentToExport = getAlignment().getHiddenSequences()
+ .getFullAlignment();
+ }
+ else
+ {
+ alignmentToExport = getAlignment();
+ }
+ alignmentStartEnd = getAlignment().getHiddenColumns()
+ .getVisibleStartAndEndIndex(alignmentToExport.getWidth());
+ AlignmentExportData ed = new AlignmentExportData(alignmentToExport,
+ omitHidden, alignmentStartEnd);
+ return ed;
+ }
+
+ @Override
+ public boolean isNormaliseSequenceLogo()
+ {
+ return normaliseSequenceLogo;
+ }
+
+ public void setNormaliseSequenceLogo(boolean state)
+ {
+ normaliseSequenceLogo = state;
+ }
+
+ @Override
+ public boolean isNormaliseHMMSequenceLogo()
+ {
+ return hmmNormaliseSequenceLogo;
+ }
+
+ public void setNormaliseHMMSequenceLogo(boolean state)
+ {
+ hmmNormaliseSequenceLogo = state;
+ }
+ /**
+ * flag set to indicate if structure views might be out of sync with sequences
+ * in the alignment
+ */
+
+ private boolean needToUpdateStructureViews = false;
+
+ @Override
+ public boolean isUpdateStructures()
+ {
+ return needToUpdateStructureViews;
+ }
+
+ @Override
+ public void setUpdateStructures(boolean update)
+ {
+ needToUpdateStructureViews = update;
+ }
+
+ @Override
+ public boolean needToUpdateStructureViews()
+ {
+ boolean update = needToUpdateStructureViews;
+ needToUpdateStructureViews = false;
+ return update;
+ }
+
+ @Override
+ public void addSequenceGroup(SequenceGroup sequenceGroup)
+ {
+ alignment.addGroup(sequenceGroup);
+
+ Color col = sequenceGroup.idColour;
+ if (col != null)
+ {
+ col = col.brighter();
+
+ for (SequenceI sq : sequenceGroup.getSequences())
+ {
+ setSequenceColour(sq, col);
+ }
+ }
+
+ if (codingComplement != null)
+ {
+ SequenceGroup mappedGroup = MappingUtils
+ .mapSequenceGroup(sequenceGroup, this, codingComplement);
+ if (mappedGroup.getSequences().size() > 0)
+ {
+ codingComplement.getAlignment().addGroup(mappedGroup);
+ if (col != null)
+ {
+ for (SequenceI seq : mappedGroup.getSequences())
+ {
+ codingComplement.setSequenceColour(seq, col);
+ }
+ }
+ }
+ // propagate the structure view update flag according to our own setting
+ codingComplement.setUpdateStructures(needToUpdateStructureViews);
+ }
+ }
+ /**
+ * Filters out sequences with an eValue higher than the specified value. The
+ * filtered sequences are hidden or deleted. Sequences with no eValues are also
+ * filtered out.
+ *
+ * @param eValue
+ * @param delete
+ */
+ public void filterByEvalue(double eValue)
+ {
+ for (SequenceI seq : alignment.getSequencesArray())
+ {
+ if ((seq.getAnnotation("Search Scores") == null
+ || seq.getAnnotation("Search Scores")[0].getEValue() > eValue)
+ && seq.getHMM() == null)
+ {
+ hideSequence(new SequenceI[] { seq });
+ }
+ }
+ }
+
+ /**
+ * Filters out sequences with an score lower than the specified value. The
+ * filtered sequences are hidden or deleted.
+ *
+ * @param score
+ * @param delete
+ */
+ public void filterByScore(double score)
+ {
+ for (SequenceI seq : alignment.getSequencesArray())
+ {
+ if ((seq.getAnnotation("Search Scores") == null
+ || seq.getAnnotation("Search Scores")[0]
+ .getBitScore() < score)
+ && seq.getHMM() == null)
+ {
+ hideSequence(new SequenceI[] { seq });
+ }
+ }
+ }
}