*/
package jalview.viewmodel;
-import java.awt.Color;
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.BitSet;
-import java.util.Deque;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
import jalview.analysis.Conservation;
-import jalview.api.AlignCalcManagerI;
+import jalview.analysis.TreeModel;
+import jalview.api.AlignCalcManagerI2;
+import jalview.api.AlignCalcWorkerI;
+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.SearchResults;
+import jalview.datamodel.ProfilesI;
+import jalview.datamodel.SearchResultsI;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceCollectionI;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
-import jalview.schemes.Blosum62ColourScheme;
+import jalview.renderer.ResidueShader;
+import jalview.renderer.ResidueShaderI;
import jalview.schemes.ColourSchemeI;
-import jalview.schemes.PIDColourScheme;
-import jalview.schemes.ResidueProperties;
import jalview.structure.CommandListener;
import jalview.structure.StructureSelectionManager;
import jalview.structure.VamsasSource;
import jalview.util.Comparison;
+import jalview.util.MapList;
import jalview.util.MappingUtils;
+import jalview.util.MessageManager;
import jalview.viewmodel.styles.ViewStyle;
-import jalview.workers.AlignCalcManager;
+import jalview.workers.AlignCalcManager2;
import jalview.workers.ComplementConsensusThread;
import jalview.workers.ConsensusThread;
+import jalview.workers.InformationThread;
import jalview.workers.StrucConsensusThread;
+import java.awt.Color;
+import java.beans.PropertyChangeSupport;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.BitSet;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+
/**
* base class holding visualization and analysis attributes and common logic for
* an active alignment view displayed in the GUI
* @author jimp
*
*/
-public abstract class AlignmentViewport implements AlignViewportI,
- CommandListener, VamsasSource
+public abstract class AlignmentViewport
+ implements AlignViewportI, CommandListener, VamsasSource
{
+ public static final String PROPERTY_ALIGNMENT = "alignment";
+ public static final String PROPERTY_SEQUENCE = "sequence";
+ protected ViewportRanges ranges;
+
protected ViewStyleI viewStyle = new ViewStyle();
/**
FeaturesDisplayedI featuresDisplayed = null;
- protected Deque<CommandI> historyList = new ArrayDeque<CommandI>();
+ protected Deque<CommandI> historyList = new ArrayDeque<>();
+
+ 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;
- protected Deque<CommandI> redoList = new ArrayDeque<CommandI>();
+ public AlignmentViewport(AlignmentI al)
+ {
+ setAlignment(al);
+ ranges = new ViewportRanges(al);
+ }
/**
* @param name
* @see jalview.api.ViewStyleI#setFontName(java.lang.String)
*/
+ @Override
public void setFontName(String name)
{
viewStyle.setFontName(name);
* @param style
* @see jalview.api.ViewStyleI#setFontStyle(int)
*/
+ @Override
public void setFontStyle(int style)
{
viewStyle.setFontStyle(style);
* @param size
* @see jalview.api.ViewStyleI#setFontSize(int)
*/
+ @Override
public void setFontSize(int size)
{
viewStyle.setFontSize(size);
* @return
* @see jalview.api.ViewStyleI#getFontStyle()
*/
+ @Override
public int getFontStyle()
{
return viewStyle.getFontStyle();
* @return
* @see jalview.api.ViewStyleI#getFontName()
*/
+ @Override
public String getFontName()
{
return viewStyle.getFontName();
* @return
* @see jalview.api.ViewStyleI#getFontSize()
*/
+ @Override
public int getFontSize()
{
return viewStyle.getFontSize();
* @param upperCasebold
* @see jalview.api.ViewStyleI#setUpperCasebold(boolean)
*/
+ @Override
public void setUpperCasebold(boolean upperCasebold)
{
viewStyle.setUpperCasebold(upperCasebold);
* @return
* @see jalview.api.ViewStyleI#isUpperCasebold()
*/
+ @Override
public boolean isUpperCasebold()
{
return viewStyle.isUpperCasebold();
* @return
* @see jalview.api.ViewStyleI#isSeqNameItalics()
*/
+ @Override
public boolean isSeqNameItalics()
{
return viewStyle.isSeqNameItalics();
* @param colourByReferenceSeq
* @see jalview.api.ViewStyleI#setColourByReferenceSeq(boolean)
*/
+ @Override
public void setColourByReferenceSeq(boolean colourByReferenceSeq)
{
viewStyle.setColourByReferenceSeq(colourByReferenceSeq);
* @param b
* @see jalview.api.ViewStyleI#setColourAppliesToAllGroups(boolean)
*/
+ @Override
public void setColourAppliesToAllGroups(boolean b)
{
viewStyle.setColourAppliesToAllGroups(b);
* @return
* @see jalview.api.ViewStyleI#getColourAppliesToAllGroups()
*/
+ @Override
public boolean getColourAppliesToAllGroups()
{
return viewStyle.getColourAppliesToAllGroups();
* @return
* @see jalview.api.ViewStyleI#getAbovePIDThreshold()
*/
+ @Override
public boolean getAbovePIDThreshold()
{
return viewStyle.getAbovePIDThreshold();
* @param inc
* @see jalview.api.ViewStyleI#setIncrement(int)
*/
+ @Override
public void setIncrement(int inc)
{
viewStyle.setIncrement(inc);
* @return
* @see jalview.api.ViewStyleI#getIncrement()
*/
+ @Override
public int getIncrement()
{
return viewStyle.getIncrement();
* @param b
* @see jalview.api.ViewStyleI#setConservationSelected(boolean)
*/
+ @Override
public void setConservationSelected(boolean b)
{
viewStyle.setConservationSelected(b);
* @param show
* @see jalview.api.ViewStyleI#setShowHiddenMarkers(boolean)
*/
+ @Override
public void setShowHiddenMarkers(boolean show)
{
viewStyle.setShowHiddenMarkers(show);
* @return
* @see jalview.api.ViewStyleI#getShowHiddenMarkers()
*/
+ @Override
public boolean getShowHiddenMarkers()
{
return viewStyle.getShowHiddenMarkers();
* @param b
* @see jalview.api.ViewStyleI#setScaleRightWrapped(boolean)
*/
+ @Override
public void setScaleRightWrapped(boolean b)
{
viewStyle.setScaleRightWrapped(b);
* @param b
* @see jalview.api.ViewStyleI#setScaleLeftWrapped(boolean)
*/
+ @Override
public void setScaleLeftWrapped(boolean b)
{
viewStyle.setScaleLeftWrapped(b);
* @param b
* @see jalview.api.ViewStyleI#setScaleAboveWrapped(boolean)
*/
+ @Override
public void setScaleAboveWrapped(boolean b)
{
viewStyle.setScaleAboveWrapped(b);
* @return
* @see jalview.api.ViewStyleI#getScaleLeftWrapped()
*/
+ @Override
public boolean getScaleLeftWrapped()
{
return viewStyle.getScaleLeftWrapped();
* @return
* @see jalview.api.ViewStyleI#getScaleAboveWrapped()
*/
+ @Override
public boolean getScaleAboveWrapped()
{
return viewStyle.getScaleAboveWrapped();
* @return
* @see jalview.api.ViewStyleI#getScaleRightWrapped()
*/
+ @Override
public boolean getScaleRightWrapped()
{
return viewStyle.getScaleRightWrapped();
* @param b
* @see jalview.api.ViewStyleI#setAbovePIDThreshold(boolean)
*/
+ @Override
public void setAbovePIDThreshold(boolean b)
{
viewStyle.setAbovePIDThreshold(b);
* @param thresh
* @see jalview.api.ViewStyleI#setThreshold(int)
*/
+ @Override
public void setThreshold(int thresh)
{
viewStyle.setThreshold(thresh);
* @return
* @see jalview.api.ViewStyleI#getThreshold()
*/
+ @Override
public int getThreshold()
{
return viewStyle.getThreshold();
* @return
* @see jalview.api.ViewStyleI#getShowJVSuffix()
*/
+ @Override
public boolean getShowJVSuffix()
{
return viewStyle.getShowJVSuffix();
* @param b
* @see jalview.api.ViewStyleI#setShowJVSuffix(boolean)
*/
+ @Override
public void setShowJVSuffix(boolean b)
{
viewStyle.setShowJVSuffix(b);
* @param state
* @see jalview.api.ViewStyleI#setWrapAlignment(boolean)
*/
+ @Override
public void setWrapAlignment(boolean state)
{
viewStyle.setWrapAlignment(state);
+ ranges.setWrappedMode(state);
}
/**
* @param state
* @see jalview.api.ViewStyleI#setShowText(boolean)
*/
+ @Override
public void setShowText(boolean state)
{
viewStyle.setShowText(state);
* @param state
* @see jalview.api.ViewStyleI#setRenderGaps(boolean)
*/
+ @Override
public void setRenderGaps(boolean state)
{
viewStyle.setRenderGaps(state);
* @return
* @see jalview.api.ViewStyleI#getColourText()
*/
+ @Override
public boolean getColourText()
{
return viewStyle.getColourText();
* @param state
* @see jalview.api.ViewStyleI#setColourText(boolean)
*/
+ @Override
public void setColourText(boolean state)
{
viewStyle.setColourText(state);
* @return
* @see jalview.api.ViewStyleI#getWrapAlignment()
*/
+ @Override
public boolean getWrapAlignment()
{
return viewStyle.getWrapAlignment();
* @return
* @see jalview.api.ViewStyleI#getShowText()
*/
+ @Override
public boolean getShowText()
{
return viewStyle.getShowText();
* @return
* @see jalview.api.ViewStyleI#getWrappedWidth()
*/
+ @Override
public int getWrappedWidth()
{
return viewStyle.getWrappedWidth();
* @param w
* @see jalview.api.ViewStyleI#setWrappedWidth(int)
*/
+ @Override
public void setWrappedWidth(int w)
{
viewStyle.setWrappedWidth(w);
* @return
* @see jalview.api.ViewStyleI#getCharHeight()
*/
+ @Override
public int getCharHeight()
{
return viewStyle.getCharHeight();
* @param h
* @see jalview.api.ViewStyleI#setCharHeight(int)
*/
+ @Override
public void setCharHeight(int h)
{
viewStyle.setCharHeight(h);
* @return
* @see jalview.api.ViewStyleI#getCharWidth()
*/
+ @Override
public int getCharWidth()
{
return viewStyle.getCharWidth();
* @param w
* @see jalview.api.ViewStyleI#setCharWidth(int)
*/
+ @Override
public void setCharWidth(int w)
{
viewStyle.setCharWidth(w);
* @return
* @see jalview.api.ViewStyleI#getShowBoxes()
*/
+ @Override
public boolean getShowBoxes()
{
return viewStyle.getShowBoxes();
* @return
* @see jalview.api.ViewStyleI#getShowUnconserved()
*/
+ @Override
public boolean getShowUnconserved()
{
return viewStyle.getShowUnconserved();
* @param showunconserved
* @see jalview.api.ViewStyleI#setShowUnconserved(boolean)
*/
+ @Override
public void setShowUnconserved(boolean showunconserved)
{
viewStyle.setShowUnconserved(showunconserved);
* @param default1
* @see jalview.api.ViewStyleI#setSeqNameItalics(boolean)
*/
+ @Override
public void setSeqNameItalics(boolean default1)
{
viewStyle.setSeqNameItalics(default1);
}
- /**
- * alignment displayed in the viewport. Please use get/setter
- */
- protected AlignmentI alignment;
-
@Override
public AlignmentI getAlignment()
{
*/
protected boolean isDataset = false;
+
public void setDataset(boolean b)
{
isDataset = b;
return isDataset;
}
-
private Map<SequenceI, SequenceCollectionI> hiddenRepSequences;
protected ColumnSelection colSel = new ColumnSelection();
- public boolean autoCalculateConsensus = true;
+ protected boolean autoCalculateConsensusAndConservation = true;
+
+ public boolean getAutoCalculateConsensusAndConservation()
+ { // BH 2019.07.24
+ return autoCalculateConsensusAndConservation;
+ }
+
+ public void setAutoCalculateConsensusAndConservation(boolean b)
+ {
+ autoCalculateConsensusAndConservation = b;
+ }
protected boolean autoCalculateStrucConsensus = true;
- protected boolean ignoreGapsInConsensusCalculation = false;
+ public boolean getAutoCalculateStrucConsensus()
+ { // BH 2019.07.24
+ return autoCalculateStrucConsensus;
+ }
- protected ColourSchemeI globalColourScheme = null;
+ public void setAutoCalculateStrucConsensus(boolean b)
+ {
+ autoCalculateStrucConsensus = b;
+ }
+ protected boolean ignoreGapsInConsensusCalculation = false;
+ protected ResidueShaderI residueShading = new ResidueShader();
+
@Override
public void setGlobalColourScheme(ColourSchemeI cs)
{
// TODO: logic refactored from AlignFrame changeColour -
- // autorecalc stuff should be changed to rely on the worker system
+ // TODO: autorecalc stuff should be changed to rely on the worker system
// check to see if we should implement a changeColour(cs) method rather than
- // put th logic in here
+ // put the logic in here
// - means that caller decides if they want to just modify state and defer
// calculation till later or to do all calculations in thread.
// via changecolour
- globalColourScheme = cs;
- boolean recalc = false;
+
+ /*
+ * only instantiate alignment colouring once, thereafter update it;
+ * this means that any conservation or PID threshold settings
+ * persist when the alignment colour scheme is changed
+ */
+ if (residueShading == null)
+ {
+ residueShading = new ResidueShader(viewStyle);
+ }
+ residueShading.setColourScheme(cs);
+
+ // TODO: do threshold and increment belong in ViewStyle or ResidueShader?
+ // ...problem: groups need these, but do not currently have a ViewStyle
+
if (cs != null)
{
- cs.setConservationApplied(recalc = getConservationSelected());
- if (getAbovePIDThreshold() || cs instanceof PIDColourScheme
- || cs instanceof Blosum62ColourScheme)
- {
- recalc = true;
- cs.setThreshold(viewStyle.getThreshold(),
- ignoreGapsInConsensusCalculation);
- }
- else
- {
- cs.setThreshold(0, ignoreGapsInConsensusCalculation);
- }
- if (recalc)
+ if (getConservationSelected())
{
- cs.setConsensus(hconsensus);
- cs.setConservation(hconservation);
+ residueShading.setConservation(hconservation);
}
- cs.alignmentChanged(alignment, hiddenRepSequences);
+ /*
+ * reset conservation flag in case just set to false if
+ * Conservation was null (calculation still in progress)
+ */
+ residueShading.setConservationApplied(getConservationSelected());
+ residueShading.alignmentChanged(alignment, hiddenRepSequences);
}
+
+ /*
+ * if 'apply colour to all groups' is selected... do so
+ * (but don't transfer any colour threshold settings to groups)
+ */
if (getColourAppliesToAllGroups())
{
for (SequenceGroup sg : getAlignment().getGroups())
{
- if (cs == null)
- {
- sg.cs = null;
- continue;
- }
- sg.cs = cs.applyTo(sg, getHiddenRepSequences());
- sg.setConsPercGaps(ConsPercGaps);
- if (getAbovePIDThreshold() || cs instanceof PIDColourScheme
- || cs instanceof Blosum62ColourScheme)
- {
- sg.cs.setThreshold(viewStyle.getThreshold(),
- isIgnoreGapsConsensus());
- recalc = true;
- }
- else
- {
- sg.cs.setThreshold(0, isIgnoreGapsConsensus());
- }
-
- if (getConservationSelected())
- {
- sg.cs.setConservationApplied(true);
- recalc = true;
- }
- else
- {
- sg.cs.setConservation(null);
- // sg.cs.setThreshold(0, getIgnoreGapsConsensus());
- }
- if (recalc)
- {
- sg.recalcConservation();
- }
- else
+ /*
+ * retain any colour thresholds per group while
+ * changing choice of colour scheme (JAL-2386)
+ */
+ sg.setColourScheme(
+ cs == null ? null : cs.getInstance(this, sg));
+ if (cs != null)
{
- sg.cs.alignmentChanged(sg, hiddenRepSequences);
+ sg.getGroupColourScheme().alignmentChanged(sg,
+ hiddenRepSequences);
}
}
}
-
}
@Override
public ColourSchemeI getGlobalColourScheme()
{
- return globalColourScheme;
+ return residueShading == null ? null : residueShading.getColourScheme();
+ }
+
+ @Override
+ public ResidueShaderI getResidueShading()
+ {
+ return residueShading;
}
+
protected AlignmentAnnotation consensus;
protected AlignmentAnnotation complementConsensus;
+ protected AlignmentAnnotation gapcounts;
+
protected AlignmentAnnotation strucConsensus;
protected AlignmentAnnotation conservation;
/**
* results of alignment consensus analysis for visible portion of view
*/
- protected Hashtable[] hconsensus = null;
+ protected ProfilesI hconsensus = null;
/**
* 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 setSequenceConsensusHash(Hashtable[] hconsensus)
+ public void setSequenceConsensusHash(ProfilesI hconsensus)
{
this.hconsensus = hconsensus;
}
@Override
- public void setComplementConsensusHash(Hashtable[] hconsensus)
+ public void setComplementConsensusHash(
+ Hashtable<String, Object>[] hconsensus)
{
this.hcomplementConsensus = hconsensus;
}
@Override
- public Hashtable[] getSequenceConsensusHash()
+ public ProfilesI getSequenceConsensusHash()
{
return hconsensus;
}
@Override
- public Hashtable[] getComplementConsensusHash()
+ public void setHmmProfiles(ProfilesI info)
+ {
+ hmmProfiles = info;
+ }
+
+ @Override
+ public ProfilesI getHmmProfiles()
+ {
+ return hmmProfiles;
+ }
+
+ @Override
+ 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 AlignmentAnnotation getAlignmentGapAnnotation()
+ {
+ return gapcounts;
+ }
+
+ @Override
public AlignmentAnnotation getComplementConsensusAnnotation()
{
return complementConsensus;
return strucConsensus;
}
- protected AlignCalcManagerI calculator = new AlignCalcManager();
+ protected AlignCalcManagerI2 calculator = new AlignCalcManager2();
/**
* trigger update of conservation annotation
public void updateConservation(final AlignmentViewPanel ap)
{
// see note in mantis : issue number 8585
- if (alignment.isNucleotide() || conservation == null
- || !autoCalculateConsensus)
+ if (alignment.isNucleotide()
+ || (conservation == null && quality == null)
+ || !autoCalculateConsensusAndConservation)
{
return;
}
- if (calculator
- .getRegisteredWorkersOfClass(jalview.workers.ConservationThread.class) == null)
+ if (calculator.getWorkersOfClass(
+ jalview.workers.ConservationThread.class).isEmpty())
{
- calculator.registerWorker(new jalview.workers.ConservationThread(
- this, ap));
+ calculator.registerWorker(
+ new jalview.workers.ConservationThread(this, ap));
}
}
public void updateConsensus(final AlignmentViewPanel ap)
{
// see note in mantis : issue number 8585
- if (consensus == null || !autoCalculateConsensus)
+ if (consensus == null || !autoCalculateConsensusAndConservation)
{
return;
}
- if (calculator.getRegisteredWorkersOfClass(ConsensusThread.class) == null)
+ if (calculator.getWorkersOfClass(ConsensusThread.class).isEmpty())
{
calculator.registerWorker(new ConsensusThread(this, ap));
}
/*
* A separate thread to compute cDNA consensus for a protein alignment
+ * which has mapping to cDNA
*/
final AlignmentI al = this.getAlignment();
if (!al.isNucleotide() && al.getCodonFrames() != null
&& !al.getCodonFrames().isEmpty())
{
- if (calculator
- .getRegisteredWorkersOfClass(ComplementConsensusThread.class) == null)
+ /*
+ * fudge - check first for protein-to-nucleotide mappings
+ * (we don't want to do this for protein-to-protein)
+ */
+ boolean doConsensus = false;
+ for (AlignedCodonFrame mapping : al.getCodonFrames())
+ {
+ // TODO hold mapping type e.g. dna-to-protein in AlignedCodonFrame?
+ MapList[] mapLists = mapping.getdnaToProt();
+ // mapLists can be empty if project load has not finished resolving seqs
+ if (mapLists.length > 0 && mapLists[0].getFromRatio() == 3)
+ {
+ doConsensus = true;
+ break;
+ }
+ }
+ if (doConsensus)
{
- calculator.registerWorker(new ComplementConsensusThread(this, ap));
+ if (calculator.getWorkersOfClass(ComplementConsensusThread.class).isEmpty())
+ {
+ calculator.registerWorker(new ComplementConsensusThread(this, ap));
+ }
}
}
}
+ @Override
+ public void initInformationWorker(final AlignmentViewPanel ap)
+ {
+ if (calculator.getWorkersOfClass(InformationThread.class).isEmpty())
+ {
+ calculator.registerWorker(new InformationThread(this, ap));
+ }
+ }
// --------START Structure Conservation
public void updateStrucConsensus(final AlignmentViewPanel ap)
{
{
return;
}
- if (calculator.getRegisteredWorkersOfClass(StrucConsensusThread.class) == null)
+ if (calculator.getWorkersOfClass(StrucConsensusThread.class).isEmpty())
{
calculator.registerWorker(new StrucConsensusThread(this, ap));
}
{
return false;
}
- if (calculator.workingInvolvedWith(alignmentAnnotation))
+ if (calculator.isWorkingWithAnnotation(alignmentAnnotation))
{
// System.err.println("grey out ("+alignmentAnnotation.label+")");
return true;
return false;
}
+ private ScheduledExecutorService serviceExecutor = Executors.newSingleThreadScheduledExecutor();
+
+ /**
+ * Get a default scheduled executor service which can be used by
+ * services and calculators to run parallel jobs associated with this
+ * viewport.
+ *
+ * @return default service executor of that viewport
+ */
+ public ScheduledExecutorService getServiceExecutor()
+ {
+ return serviceExecutor;
+ }
+
+ public void setAlignment(AlignmentI align)
+ {
+ this.alignment = align;
+ }
+
+ /**
+ * Clean up references when this viewport is closed
+ */
+ @Override
+ public void dispose()
+ {
+ /*
+ * defensively null out references to large objects in case
+ * this object is not garbage collected (as if!)
+ */
+ consensus = null;
+ complementConsensus = null;
+ strucConsensus = null;
+ conservation = null;
+ quality = null;
+ consensusProfiles = null;
+ groupConsensus = null;
+ groupConservation = null;
+ hconsensus = null;
+ hconservation = null;
+ hcomplementConsensus = null;
+ gapcounts = null;
+ calculator.shutdown();
+ calculator = null;
+ serviceExecutor.shutdown();
+ serviceExecutor = null;
+ residueShading = null; // may hold a reference to Consensus
+ changeSupport = null;
+ ranges = null;
+ currentTree = null;
+ selectionGroup = null;
+ colSel = null;
+ setAlignment(null);
+ }
+
@Override
public boolean isClosed()
{
}
@Override
- public AlignCalcManagerI getCalcManager()
+ public AlignCalcManagerI2 getCalcManager()
{
return calculator;
}
protected boolean showConsensusHistogram = true;
/**
+ * should hmm profile be rendered by default
+ */
+ protected boolean hmmShowSequenceLogo = false;
+
+ /**
+ * should hmm profile be rendered normalised to row height
+ */
+ protected boolean hmmNormaliseSequenceLogo = false;
+
+ /**
+ * should information histograms be rendered by default
+ */
+ protected boolean hmmShowHistogram = true;
+
+ /**
* @return the showConsensusProfile
*/
@Override
}
/**
+ * @return the showInformationProfile
+ */
+ @Override
+ public boolean isShowHMMSequenceLogo()
+ {
+ return hmmShowSequenceLogo;
+ }
+
+ /**
* @param showSequenceLogo
* the new value
*/
// TODO: decouple settings setting from calculation when refactoring
// annotation update method from alignframe to viewport
this.showSequenceLogo = showSequenceLogo;
- calculator.updateAnnotationFor(ConsensusThread.class);
- calculator.updateAnnotationFor(ComplementConsensusThread.class);
- calculator.updateAnnotationFor(StrucConsensusThread.class);
+ for (AlignCalcWorkerI worker : calculator.getWorkers())
+ {
+ if (worker.getClass().equals(ConsensusThread.class) ||
+ worker.getClass().equals(ComplementConsensusThread.class) ||
+ worker.getClass().equals(StrucConsensusThread.class))
+ {
+ worker.updateAnnotation();
+ }
+ }
}
this.showSequenceLogo = showSequenceLogo;
}
+ public void setShowHMMSequenceLogo(boolean showHMMSequenceLogo)
+ {
+ if (showHMMSequenceLogo != this.hmmShowSequenceLogo)
+ {
+ this.hmmShowSequenceLogo = showHMMSequenceLogo;
+ // TODO: updateAnnotation if description (tooltip) will show
+ // profile in place of information content?
+ // calculator.updateAnnotationFor(InformationThread.class);
+ }
+ this.hmmShowSequenceLogo = showHMMSequenceLogo;
+ }
/**
* @param showConsensusHistogram
* the showConsensusHistogram to set
}
/**
+ * @param showInformationHistogram
+ */
+ public void setShowInformationHistogram(boolean showInformationHistogram)
+ {
+ this.hmmShowHistogram = showInformationHistogram;
+ }
+
+ /**
* @return the showGroupConservation
*/
public boolean isShowGroupConservation()
}
/**
+ *
+ * @return flag to indicate if the information content histogram should be
+ * rendered by default
+ */
+ @Override
+ public boolean isShowInformationHistogram()
+ {
+ return this.hmmShowHistogram;
+ }
+
+ /**
* when set, updateAlignment will always ensure sequences are of equal length
*/
private boolean padGaps = false;
*/
public boolean sortByTree = false;
-
/**
*
*
}
/**
- * Set the selection group for this window.
+ * Set the selection group for this window. Also sets the current alignment as
+ * the context for the group, if it does not already have one.
*
* @param sg
* - group holding references to sequences in this alignment view
public void setSelectionGroup(SequenceGroup sg)
{
selectionGroup = sg;
+ if (sg != null && sg.getContext() == null)
+ {
+ sg.setContext(alignment);
+ }
}
- public void setHiddenColumns(ColumnSelection colsel)
+ public void setHiddenColumns(HiddenColumns hidden)
{
- this.colSel = colsel;
+ this.alignment.setHiddenColumns(hidden);
}
@Override
{
updateHiddenColumns();
}
+ isColSelChanged(true);
}
/**
}
@Override
+ public boolean hasSelectedColumns()
+ {
+ ColumnSelection columnSelection = getColumnSelection();
+ return columnSelection != null && columnSelection.hasSelectedColumns();
+ }
+
+ @Override
public boolean hasHiddenColumns()
{
- return colSel != null && colSel.hasHiddenColumns();
+ return alignment.getHiddenColumns() != null
+ && alignment.getHiddenColumns().hasHiddenColumns();
}
public void updateHiddenColumns()
// hasHiddenColumns = colSel.hasHiddenColumns();
}
- protected boolean hasHiddenRows = false;
-
@Override
public boolean hasHiddenRows()
{
- return hasHiddenRows;
+ return alignment.getHiddenSequences().getSize() > 0;
}
protected SequenceGroup selectionGroup;
{
if (sequenceSetID != null)
{
- System.err
- .println("Warning - overwriting a sequenceSetId for a viewport!");
+ System.err.println(
+ "Warning - overwriting a sequenceSetId for a viewport!");
}
sequenceSetID = new String(newid);
}
if (ap != null)
{
updateConsensus(ap);
- if (globalColourScheme != null)
+ if (residueShading != null)
{
- globalColourScheme.setThreshold(globalColourScheme.getThreshold(),
+ residueShading.setThreshold(residueShading.getThreshold(),
ignoreGapsInConsensusCalculation);
}
}
+ }
+
+ public void setIgnoreBelowBackground(boolean b, AlignmentViewPanel ap)
+ {
+ ignoreBelowBackGroundFrequencyCalculation = b;
+ }
+ public void setInfoLetterHeight(boolean b, AlignmentViewPanel ap)
+ {
+ infoLetterHeight = b;
}
private long sgrouphash = -1, colselhash = -1;
* checks current colsel against record of last hash value, and optionally
* updates record.
*
- * @param b
+ * @param updateHash
* update the record of last hash value
* @return true if colsel changed since last call (when b is true)
*/
- public boolean isColSelChanged(boolean b)
+ public boolean isColSelChanged(boolean updateHash)
{
- int hc = (colSel == null || colSel.size() == 0) ? -1 : colSel
- .hashCode();
+ int hc = (colSel == null || colSel.isEmpty()) ? -1 : colSel.hashCode();
if (hc != -1 && hc != colselhash)
{
- if (b)
+ if (updateHash)
{
colselhash = hc;
}
return true;
}
+ notifySequence();
return false;
}
return ignoreGapsInConsensusCalculation;
}
- // / property change stuff
+ @Override
+ public boolean isIgnoreBelowBackground()
+ {
+ return ignoreBelowBackGroundFrequencyCalculation;
+ }
+ @Override
+ public boolean isInfoLetterHeight()
+ {
+ return infoLetterHeight;
+ }
+ // property change stuff
// JBPNote Prolly only need this in the applet version.
- private final java.beans.PropertyChangeSupport changeSupport = new java.beans.PropertyChangeSupport(
+ private PropertyChangeSupport changeSupport = new PropertyChangeSupport(
this);
protected boolean showConservation = true;
protected boolean showConsensus = true;
- private Map<SequenceI, Color> sequenceColours = new HashMap<SequenceI, Color>();
+ protected boolean showOccupancy = true;
+
+ private Map<SequenceI, Color> sequenceColours = new HashMap<>();
protected SequenceAnnotationOrder sortAnnotationsBy = null;
*/
private boolean followHighlight = true;
- // TODO private with getters and setters?
- public int startRes;
-
- public int endRes;
-
- public int startSeq;
-
- public int endSeq;
-
/**
* Property change listener for changes in alignment
*
public void removePropertyChangeListener(
java.beans.PropertyChangeListener listener)
{
- changeSupport.removePropertyChangeListener(listener);
+ if (changeSupport != null)
+ {
+ changeSupport.removePropertyChangeListener(listener);
+ }
}
- /**
- * Property change listener for changes in alignment
- *
- * @param prop
- * DOCUMENT ME!
- * @param oldvalue
- * DOCUMENT ME!
- * @param newvalue
- * DOCUMENT ME!
- */
- public void firePropertyChange(String prop, Object oldvalue,
- Object newvalue)
- {
- changeSupport.firePropertyChange(prop, oldvalue, newvalue);
- }
// common hide/show column stuff
public void hideSelectedColumns()
{
- if (colSel.size() < 1)
+ if (colSel.isEmpty())
{
return;
}
- colSel.hideSelectedColumns();
+ colSel.hideSelectedColumns(alignment);
setSelectionGroup(null);
-
+ isColSelChanged(true);
}
public void hideColumns(int start, int end)
{
if (start == end)
{
- colSel.hideColumns(start);
+ colSel.hideSelectedColumns(start, alignment.getHiddenColumns());
}
else
{
- colSel.hideColumns(start, end);
+ alignment.getHiddenColumns().hideColumns(start, end);
}
+ isColSelChanged(true);
}
public void showColumn(int col)
{
- colSel.revealHiddenColumns(col);
-
+ alignment.getHiddenColumns().revealHiddenColumns(col, colSel);
+ isColSelChanged(true);
}
public void showAllHiddenColumns()
{
- colSel.revealAllHiddenColumns();
+ alignment.getHiddenColumns().revealAllHiddenColumns(colSel);
+ isColSelChanged(true);
}
// common hide/show seq stuff
public void showAllHiddenSeqs()
{
+ int startSeq = ranges.getStartSeq();
+ int endSeq = ranges.getEndSeq();
+
if (alignment.getHiddenSequences().getSize() > 0)
{
if (selectionGroup == null)
selectionGroup = new SequenceGroup();
selectionGroup.setEndRes(alignment.getWidth() - 1);
}
- List<SequenceI> tmp = alignment.getHiddenSequences().showAll(
- hiddenRepSequences);
+ List<SequenceI> tmp = alignment.getHiddenSequences()
+ .showAll(hiddenRepSequences);
for (SequenceI seq : tmp)
{
selectionGroup.addSequence(seq, false);
setSequenceAnnotationsVisible(seq, true);
}
- hasHiddenRows = false;
hiddenRepSequences = null;
- firePropertyChange("alignment", null, alignment.getSequences());
+ ranges.setStartEndSeq(startSeq, endSeq + tmp.size());
+
// used to set hasHiddenRows/hiddenRepSequences here, after the property
// changed event
+ notifySequence();
sendSelection();
}
}
public void showSequence(int index)
{
- List<SequenceI> tmp = alignment.getHiddenSequences().showSequence(
- 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);
}
- // JBPNote: refactor: only update flag if we modified visiblity (used to
- // do this regardless)
- if (alignment.getHiddenSequences().getSize() < 1)
- {
- hasHiddenRows = false;
- }
- firePropertyChange("alignment", null, alignment.getSequences());
+
+ ranges.setStartEndSeq(startSeq, endSeq + tmp.size());
+
+ notifyAlignment();
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);
}
- hasHiddenRows = true;
- firePropertyChange("alignment", null, alignment.getSequences());
+ ranges.setStartSeq(startSeq);
+ notifyAlignment();
}
}
/**
+ * Hides the specified sequence, or the sequences it represents
+ *
+ * @param sequence
+ * the sequence to hide, or keep as representative
+ * @param representGroup
+ * if true, hide the current selection group except for the
+ * representative sequence
+ */
+ public void hideSequences(SequenceI sequence, boolean representGroup)
+ {
+ if (selectionGroup == null || selectionGroup.getSize() < 1)
+ {
+ hideSequence(new SequenceI[] { sequence });
+ return;
+ }
+
+ if (representGroup)
+ {
+ hideRepSequences(sequence, selectionGroup);
+ setSelectionGroup(null);
+ return;
+ }
+
+ int gsize = selectionGroup.getSize();
+ SequenceI[] hseqs = selectionGroup.getSequences()
+ .toArray(new SequenceI[gsize]);
+
+ hideSequence(hseqs);
+ setSelectionGroup(null);
+ sendSelection();
+ }
+
+ /**
* Set visibility for any annotations for the given sequence.
*
* @param sequenceI
protected void setSequenceAnnotationsVisible(SequenceI sequenceI,
boolean visible)
{
- for (AlignmentAnnotation ann : alignment.getAlignmentAnnotation())
+ AlignmentAnnotation[] anns = alignment.getAlignmentAnnotation();
+ if (anns != null)
{
- if (ann.sequenceRef == sequenceI)
+ for (AlignmentAnnotation ann : anns)
{
- ann.visible = visible;
+ if (ann.sequenceRef == sequenceI)
+ {
+ ann.visible = visible;
+ }
}
}
}
if (hiddenRepSequences == null)
{
- hiddenRepSequences = new Hashtable();
+ hiddenRepSequences = new Hashtable<>();
}
hiddenRepSequences.put(repSequence, sg);
}
+ /**
+ *
+ * @return null or the current reference sequence
+ */
+ public SequenceI getReferenceSeq()
+ {
+ return alignment.getSeqrep();
+ }
+
+ /**
+ * @param seq
+ * @return true iff seq is the reference for the alignment
+ */
+ public boolean isReferenceSeq(SequenceI seq)
+ {
+ return alignment.getSeqrep() == seq;
+ }
+
+ /**
+ *
+ * @param seq
+ * @return true if there are sequences represented by this sequence that are
+ * currently hidden
+ */
public boolean isHiddenRepSequence(SequenceI seq)
{
- return alignment.getSeqrep()==seq || (hiddenRepSequences != null
+ return (hiddenRepSequences != null
&& hiddenRepSequences.containsKey(seq));
}
+ /**
+ *
+ * @param seq
+ * @return null or a sequence group containing the sequences that seq
+ * represents
+ */
public SequenceGroup getRepresentedSequences(SequenceI seq)
{
return (SequenceGroup) (hiddenRepSequences == null ? null
@Override
public int adjustForHiddenSeqs(int alignmentIndex)
{
- return alignment.getHiddenSequences().adjustForHiddenSeqs(
- alignmentIndex);
+ return alignment.getHiddenSequences()
+ .adjustForHiddenSeqs(alignmentIndex);
}
@Override
public void invertColumnSelection()
{
- colSel.invertColumnSelection(0, alignment.getWidth());
+ colSel.invertColumnSelection(0, alignment.getWidth(), alignment);
+ isColSelChanged(true);
}
-
@Override
public SequenceI[] getSelectionAsNewSequence()
{
return sequences;
}
-
@Override
public SequenceI[] getSequenceSelection()
{
return sequences;
}
-
- @Override
- public CigarArray getViewAsCigars(
- boolean selectedRegionOnly)
- {
- return new CigarArray(alignment, colSel,
- (selectedRegionOnly ? selectionGroup : null));
- }
-
-
@Override
public jalview.datamodel.AlignmentView getAlignmentView(
boolean selectedOnly)
return getAlignmentView(selectedOnly, false);
}
-
@Override
public jalview.datamodel.AlignmentView getAlignmentView(
boolean selectedOnly, boolean markGroups)
{
- return new AlignmentView(alignment, colSel, selectionGroup,
- colSel != null && colSel.hasHiddenColumns(), selectedOnly,
- markGroups);
+ return new AlignmentView(alignment, alignment.getHiddenColumns(),
+ selectionGroup,
+ alignment.getHiddenColumns() != null
+ && alignment.getHiddenColumns().hasHiddenColumns(),
+ selectedOnly, markGroups);
}
-
@Override
public String[] getViewAsString(boolean selectedRegionOnly)
{
+ return getViewAsString(selectedRegionOnly, true);
+ }
+
+ @Override
+ public String[] getViewAsString(boolean selectedRegionOnly,
+ boolean exportHiddenSeqs)
+ {
String[] selection = null;
SequenceI[] seqs = null;
int i, iSize;
}
else
{
- iSize = alignment.getHeight();
- seqs = alignment.getSequencesArray();
- end = alignment.getWidth();
+ if (hasHiddenRows() && exportHiddenSeqs)
+ {
+ AlignmentI fullAlignment = alignment.getHiddenSequences()
+ .getFullAlignment();
+ iSize = fullAlignment.getHeight();
+ seqs = fullAlignment.getSequencesArray();
+ end = fullAlignment.getWidth();
+ }
+ else
+ {
+ iSize = alignment.getHeight();
+ seqs = alignment.getSequencesArray();
+ end = alignment.getWidth();
+ }
}
selection = new String[iSize];
- if (colSel != null && colSel.hasHiddenColumns())
+ if (alignment.getHiddenColumns() != null
+ && alignment.getHiddenColumns().hasHiddenColumns())
{
- selection = colSel.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
{
return selection;
}
-
@Override
public List<int[]> getVisibleRegionBoundaries(int min, int max)
{
- ArrayList<int[]> regions = new ArrayList<int[]>();
+ ArrayList<int[]> regions = new ArrayList<>();
int start = min;
int end = max;
do
{
- if (colSel != null && colSel.hasHiddenColumns())
+ HiddenColumns hidden = alignment.getHiddenColumns();
+ if (hidden != null && hidden.hasHiddenColumns())
{
if (start == 0)
{
- start = colSel.adjustForHiddenColumns(start);
+ start = hidden.visibleToAbsoluteColumn(start);
}
- end = colSel.getHiddenBoundaryRight(start);
+ end = hidden.getNextHiddenBoundary(false, start);
if (start == end)
{
end = max;
}
}
- regions.add(new int[]
- { start, end });
+ regions.add(new int[] { start, end });
- if (colSel != null && colSel.hasHiddenColumns())
+ if (hidden != null && hidden.hasHiddenColumns())
{
- start = colSel.adjustForHiddenColumns(end);
- start = colSel.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;
}
@Override
- public List<AlignmentAnnotation> getVisibleAlignmentAnnotation(boolean selectedOnly)
+ public List<AlignmentAnnotation> getVisibleAlignmentAnnotation(
+ boolean selectedOnly)
{
- ArrayList<AlignmentAnnotation> ala = new ArrayList<AlignmentAnnotation>();
+ ArrayList<AlignmentAnnotation> ala = new ArrayList<>();
AlignmentAnnotation[] aa;
- if ((aa=alignment.getAlignmentAnnotation())!=null)
+ if ((aa = alignment.getAlignmentAnnotation()) != null)
{
- for (AlignmentAnnotation annot:aa)
+ for (AlignmentAnnotation annot : aa)
{
AlignmentAnnotation clone = new AlignmentAnnotation(annot);
- if (selectedOnly && selectionGroup!=null)
+ if (selectedOnly && selectionGroup != null)
{
- colSel.makeVisibleAnnotation(selectionGroup.getStartRes(), selectionGroup.getEndRes(),clone);
- } else {
- colSel.makeVisibleAnnotation(clone);
+ clone.makeVisibleAnnotation(
+ selectionGroup.getStartRes(), selectionGroup.getEndRes(),
+ alignment.getHiddenColumns());
+ }
+ else
+ {
+ clone.makeVisibleAnnotation(alignment.getHiddenColumns());
}
ala.add(clone);
}
return ala;
}
-
@Override
public boolean isPadGaps()
{
return padGaps;
}
-
@Override
public void setPadGaps(boolean padGaps)
{
{
alignment.padGaps();
}
- if (autoCalculateConsensus)
+ if (autoCalculateConsensusAndConservation)
{
updateConsensus(ap);
}
- if (hconsensus != null && autoCalculateConsensus)
+ if (hconsensus != null && autoCalculateConsensusAndConservation)
{
updateConservation(ap);
}
selectionGroup.setEndRes(alWidth - 1);
}
- resetAllColourSchemes();
+ updateAllColourSchemes();
calculator.restartWorkers();
- // alignment.adjustSequenceAnnotations();
}
/**
* reset scope and do calculations for all applied colourschemes on alignment
*/
- void resetAllColourSchemes()
+ void updateAllColourSchemes()
{
- ColourSchemeI cs = globalColourScheme;
- if (cs != null)
+ ResidueShaderI rs = residueShading;
+ if (rs != null)
{
- cs.alignmentChanged(alignment, hiddenRepSequences);
+ rs.alignmentChanged(alignment, hiddenRepSequences);
- cs.setConsensus(hconsensus);
- if (cs.conservationApplied())
+ rs.setConsensus(hconsensus);
+ if (rs.conservationApplied())
{
- cs.setConservation(Conservation.calculateConservation("All",
- ResidueProperties.propHash, 3, alignment.getSequences(), 0,
- alignment.getWidth(), false, getConsPercGaps(), false));
+ rs.setConservation(Conservation.calculateConservation("All",
+ alignment.getSequences(), 0, alignment.getWidth(), false,
+ getConsPercGaps(), false));
}
}
{
initRNAStructure();
}
- consensus = new AlignmentAnnotation("Consensus", "PID",
+ consensus = new AlignmentAnnotation("Consensus",
+ MessageManager.getString("label.consensus_descr"),
new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH);
initConsensus(consensus);
+ initGapCounts();
initComplementConsensus();
}
}
/**
- * If this is a protein alignment and there are mappings to cDNA, add the cDNA
- * consensus annotation.
+ * If this is a protein alignment and there are mappings to cDNA, adds the
+ * cDNA consensus annotation and returns true, else returns false.
*/
- public void initComplementConsensus()
+ public boolean initComplementConsensus()
{
if (!alignment.isNucleotide())
{
- final Set<AlignedCodonFrame> codonMappings = alignment
+ final List<AlignedCodonFrame> codonMappings = alignment
.getCodonFrames();
if (codonMappings != null && !codonMappings.isEmpty())
{
- complementConsensus = new AlignmentAnnotation("cDNA Consensus",
- "PID for cDNA", new Annotation[1], 0f, 100f,
- AlignmentAnnotation.BAR_GRAPH);
- initConsensus(complementConsensus);
+ boolean doConsensus = false;
+ for (AlignedCodonFrame mapping : codonMappings)
+ {
+ // TODO hold mapping type e.g. dna-to-protein in AlignedCodonFrame?
+ MapList[] mapLists = mapping.getdnaToProt();
+ // mapLists can be empty if project load has not finished resolving
+ // seqs
+ if (mapLists.length > 0 && mapLists[0].getFromRatio() == 3)
+ {
+ doConsensus = true;
+ break;
+ }
+ }
+ if (doConsensus)
+ {
+ complementConsensus = new AlignmentAnnotation("cDNA Consensus",
+ MessageManager
+ .getString("label.complement_consensus_descr"),
+ new Annotation[1], 0f, 100f,
+ AlignmentAnnotation.BAR_GRAPH);
+ initConsensus(complementConsensus);
+ return true;
+ }
}
}
+ return false;
}
private void initConsensus(AlignmentAnnotation aa)
}
}
+ // these should be extracted from the view model - style and settings for
+ // derived annotation
+ private void initGapCounts()
+ {
+ if (showOccupancy)
+ {
+ gapcounts = new AlignmentAnnotation("Occupancy",
+ MessageManager.getString("label.occupancy_descr"),
+ new Annotation[1], 0f, alignment.getHeight(),
+ AlignmentAnnotation.BAR_GRAPH);
+ gapcounts.hasText = true;
+ gapcounts.autoCalculated = true;
+ gapcounts.scaleColLabel = true;
+ gapcounts.graph = AlignmentAnnotation.BAR_GRAPH;
+
+ alignment.addAnnotation(gapcounts);
+ }
+ }
+
private void initConservation()
{
if (showConservation)
if (conservation == null)
{
conservation = new AlignmentAnnotation("Conservation",
- "Conservation of total alignment less than "
- + getConsPercGaps() + "% gaps", new Annotation[1],
- 0f, 11f, AlignmentAnnotation.BAR_GRAPH);
+ MessageManager.formatMessage("label.conservation_descr",
+ getConsPercGaps()),
+ new Annotation[1], 0f, 11f, AlignmentAnnotation.BAR_GRAPH);
conservation.hasText = true;
conservation.autoCalculated = true;
alignment.addAnnotation(conservation);
if (quality == null)
{
quality = new AlignmentAnnotation("Quality",
- "Alignment Quality based on Blosum62 scores",
+ MessageManager.getString("label.quality_descr"),
new Annotation[1], 0f, 11f, AlignmentAnnotation.BAR_GRAPH);
quality.hasText = true;
quality.autoCalculated = true;
{
if (alignment.hasRNAStructure() && strucConsensus == null)
{
- strucConsensus = new AlignmentAnnotation("StrucConsensus", "PID",
+ strucConsensus = new AlignmentAnnotation("StrucConsensus",
+ MessageManager.getString("label.strucconsensus_descr"),
new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH);
strucConsensus.hasText = true;
strucConsensus.autoCalculated = true;
boolean showprf = isShowSequenceLogo();
boolean showConsHist = isShowConsensusHistogram();
boolean normLogo = isNormaliseSequenceLogo();
+ boolean showHMMPrf = isShowHMMSequenceLogo();
+ boolean showInfoHist = isShowInformationHistogram();
+ boolean normHMMLogo = isNormaliseHMMSequenceLogo();
/**
* 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
// intersect alignment annotation with alignment groups
AlignmentAnnotation[] aan = alignment.getAlignmentAnnotation();
- List<SequenceGroup> oldrfs = new ArrayList<SequenceGroup>();
+ List<SequenceGroup> oldrfs = new ArrayList<>();
if (aan != null)
{
for (int an = 0; an < aan.length; an++)
sg.setshowSequenceLogo(showprf);
sg.setShowConsensusHistogram(showConsHist);
sg.setNormaliseSequenceLogo(normLogo);
+ sg.setShowHMMSequenceLogo(showHMMPrf);
+ sg.setShowInformationHistogram(showInfoHist);
+ sg.setNormaliseHMMSequenceLogo(normHMMLogo);
}
if (conv)
{
}
oldrfs.clear();
}
+
@Override
public boolean isDisplayReferenceSeq()
{
public void clearSequenceColours()
{
sequenceColours.clear();
- };
+ }
@Override
public AlignViewportI getCodingComplement()
@Override
public boolean areFeaturesDisplayed()
{
- return featuresDisplayed != null && featuresDisplayed.getRegisterdFeaturesCount()>0;
+ return featuresDisplayed != null
+ && featuresDisplayed.getRegisteredFeaturesCount() > 0;
}
/**
{
viewStyle.setShowSequenceFeatures(b);
}
+
@Override
public boolean isShowSequenceFeatures()
{
return viewStyle.isShowSequenceFeaturesHeight();
}
-
-
@Override
public void setShowAnnotation(boolean b)
{
* @return
* @see jalview.api.ViewStyleI#getTextColour()
*/
+ @Override
public Color getTextColour()
{
return viewStyle.getTextColour();
* @return
* @see jalview.api.ViewStyleI#getTextColour2()
*/
+ @Override
public Color getTextColour2()
{
return viewStyle.getTextColour2();
* @return
* @see jalview.api.ViewStyleI#getThresholdTextColour()
*/
+ @Override
public int getThresholdTextColour()
{
return viewStyle.getThresholdTextColour();
* @return
* @see jalview.api.ViewStyleI#isConservationColourSelected()
*/
+ @Override
public boolean isConservationColourSelected()
{
return viewStyle.isConservationColourSelected();
* @return
* @see jalview.api.ViewStyleI#isRenderGaps()
*/
+ @Override
public boolean isRenderGaps()
{
return viewStyle.isRenderGaps();
* @return
* @see jalview.api.ViewStyleI#isShowColourText()
*/
+ @Override
public boolean isShowColourText()
{
return viewStyle.isShowColourText();
* @param conservationColourSelected
* @see jalview.api.ViewStyleI#setConservationColourSelected(boolean)
*/
+ @Override
public void setConservationColourSelected(
boolean conservationColourSelected)
{
* @param showColourText
* @see jalview.api.ViewStyleI#setShowColourText(boolean)
*/
+ @Override
public void setShowColourText(boolean showColourText)
{
viewStyle.setShowColourText(showColourText);
* @param textColour
* @see jalview.api.ViewStyleI#setTextColour(java.awt.Color)
*/
+ @Override
public void setTextColour(Color textColour)
{
viewStyle.setTextColour(textColour);
* @param thresholdTextColour
* @see jalview.api.ViewStyleI#setThresholdTextColour(int)
*/
+ @Override
public void setThresholdTextColour(int thresholdTextColour)
{
viewStyle.setThresholdTextColour(thresholdTextColour);
* @param textColour2
* @see jalview.api.ViewStyleI#setTextColour2(java.awt.Color)
*/
+ @Override
public void setTextColour2(Color textColour2)
{
viewStyle.setTextColour2(textColour2);
public void setViewStyle(ViewStyleI settingsForView)
{
viewStyle = new ViewStyle(settingsForView);
+ if (residueShading != null)
+ {
+ residueShading.setConservationApplied(
+ settingsForView.isConservationColourSelected());
+ }
}
@Override
* @return
* @see jalview.api.ViewStyleI#getIdWidth()
*/
+ @Override
public int getIdWidth()
{
return viewStyle.getIdWidth();
* @param i
* @see jalview.api.ViewStyleI#setIdWidth(int)
*/
+ @Override
public void setIdWidth(int i)
{
viewStyle.setIdWidth(i);
* @return
* @see jalview.api.ViewStyleI#isCentreColumnLabels()
*/
+ @Override
public boolean isCentreColumnLabels()
{
return viewStyle.isCentreColumnLabels();
* @param centreColumnLabels
* @see jalview.api.ViewStyleI#setCentreColumnLabels(boolean)
*/
+ @Override
public void setCentreColumnLabels(boolean centreColumnLabels)
{
viewStyle.setCentreColumnLabels(centreColumnLabels);
* @param showdbrefs
* @see jalview.api.ViewStyleI#setShowDBRefs(boolean)
*/
+ @Override
public void setShowDBRefs(boolean showdbrefs)
{
viewStyle.setShowDBRefs(showdbrefs);
* @return
* @see jalview.api.ViewStyleI#isShowDBRefs()
*/
+ @Override
public boolean isShowDBRefs()
{
return viewStyle.isShowDBRefs();
* @return
* @see jalview.api.ViewStyleI#isShowNPFeats()
*/
+ @Override
public boolean isShowNPFeats()
{
return viewStyle.isShowNPFeats();
* @param shownpfeats
* @see jalview.api.ViewStyleI#setShowNPFeats(boolean)
*/
+ @Override
public void setShowNPFeats(boolean shownpfeats)
{
viewStyle.setShowNPFeats(shownpfeats);
protected void broadcastCommand(CommandI command, boolean undo)
{
- getStructureSelectionManager().commandPerformed(command, undo, getVamsasSource());
+ getStructureSelectionManager().commandPerformed(command, undo,
+ getVamsasSource());
}
/**
return sortAnnotationsBy;
}
- public void setSortAnnotationsBy(SequenceAnnotationOrder sortAnnotationsBy)
+ public void setSortAnnotationsBy(
+ SequenceAnnotationOrder sortAnnotationsBy)
{
this.sortAnnotationsBy = sortAnnotationsBy;
}
viewStyle.setScaleProteinAsCdna(b);
}
- /**
- * @return true if view should scroll to show the highlighted region of a
- * sequence
- * @return
- */
@Override
- public final boolean isFollowHighlight()
+ public boolean isProteinFontAsCdna()
{
- return followHighlight;
+ return viewStyle.isProteinFontAsCdna();
}
@Override
- public final void setFollowHighlight(boolean b)
- {
- this.followHighlight = b;
- }
-
- public int getStartRes()
+ public void setProteinFontAsCdna(boolean b)
{
- return startRes;
+ viewStyle.setProteinFontAsCdna(b);
}
- public int getEndRes()
+ @Override
+ public void setShowComplementFeatures(boolean b)
{
- return endRes;
+ viewStyle.setShowComplementFeatures(b);
}
- public int getStartSeq()
+ @Override
+ public boolean isShowComplementFeatures()
{
- return startSeq;
+ return viewStyle.isShowComplementFeatures();
}
- public void setStartRes(int res)
+ @Override
+ public void setShowComplementFeaturesOnTop(boolean b)
{
- this.startRes = res;
+ viewStyle.setShowComplementFeaturesOnTop(b);
}
- public void setStartSeq(int seq)
+ @Override
+ public boolean isShowComplementFeaturesOnTop()
{
- this.startSeq = seq;
+ return viewStyle.isShowComplementFeaturesOnTop();
}
- public void setEndRes(int res)
+ /**
+ * @return true if view should scroll to show the highlighted region of a
+ * sequence
+ * @return
+ */
+ @Override
+ public final boolean isFollowHighlight()
{
- if (res > alignment.getWidth() - 1)
- {
- // log.System.out.println(" Corrected res from " + res + " to maximum " +
- // (alignment.getWidth()-1));
- res = alignment.getWidth() - 1;
- }
- if (res < 0)
- {
- res = 0;
- }
- this.endRes = res;
+ return followHighlight;
}
- public void setEndSeq(int seq)
+ @Override
+ public final void setFollowHighlight(boolean b)
{
- if (seq > alignment.getHeight())
- {
- seq = alignment.getHeight();
- }
- if (seq < 0)
- {
- seq = 0;
- }
- this.endSeq = seq;
+ this.followHighlight = b;
}
- public int getEndSeq()
+ @Override
+ public ViewportRanges getRanges()
{
- return endSeq;
+ return ranges;
}
/**
* the SearchResults to add to
* @return the offset (below top of visible region) of the matched sequence
*/
- protected int findComplementScrollTarget(SearchResults sr)
+ protected int findComplementScrollTarget(SearchResultsI sr)
{
- final AlignViewportI codingComplement = getCodingComplement();
- if (codingComplement == null || !codingComplement.isFollowHighlight())
+ final AlignViewportI complement = getCodingComplement();
+ if (complement == null || !complement.isFollowHighlight())
{
return 0;
}
boolean iAmProtein = !getAlignment().isNucleotide();
AlignmentI proteinAlignment = iAmProtein ? getAlignment()
- : codingComplement.getAlignment();
+ : complement.getAlignment();
if (proteinAlignment == null)
{
return 0;
}
- final Set<AlignedCodonFrame> mappings = proteinAlignment
+ final List<AlignedCodonFrame> mappings = proteinAlignment
.getCodonFrames();
-
+
/*
* Heuristic: find the first mapped sequence (if any) with a non-gapped
* residue in the middle column of the visible region. Scroll the
* locate 'middle' column (true middle if an odd number visible, left of
* middle if an even number visible)
*/
- int middleColumn = getStartRes() + (getEndRes() - getStartRes()) / 2;
+ int middleColumn = ranges.getStartRes()
+ + (ranges.getEndRes() - ranges.getStartRes()) / 2;
final HiddenSequences hiddenSequences = getAlignment()
.getHiddenSequences();
- for (int seqNo = getStartSeq(); seqNo < getEndSeq(); seqNo++, seqOffset++)
+
+ /*
+ * searching to the bottom of the alignment gives smoother scrolling across
+ * all gapped visible regions
+ */
+ int lastSeq = alignment.getHeight() - 1;
+ List<AlignedCodonFrame> seqMappings = null;
+ for (int seqNo = ranges
+ .getStartSeq(); seqNo <= lastSeq; seqNo++, seqOffset++)
{
sequence = getAlignment().getSequenceAt(seqNo);
if (hiddenSequences != null && hiddenSequences.isHidden(sequence))
{
continue;
}
- List<AlignedCodonFrame> seqMappings = MappingUtils
- .findMappingsForSequence(sequence, mappings);
+ seqMappings = MappingUtils.findMappingsForSequenceAndOthers(sequence,
+ mappings,
+ getCodingComplement().getAlignment().getSequences());
if (!seqMappings.isEmpty())
{
break;
}
}
-
- if (sequence == null)
+
+ if (sequence == null || seqMappings == null || seqMappings.isEmpty())
{
/*
* No ungapped mapped sequence in middle column - do nothing
return 0;
}
MappingUtils.addSearchResults(sr, sequence,
- sequence.findPosition(middleColumn), mappings);
+ sequence.findPosition(middleColumn), seqMappings);
return seqOffset;
}
+
+ /**
+ * synthesize a column selection if none exists so it covers the given
+ * selection group. if wholewidth is false, no column selection is made if the
+ * selection group covers the whole alignment width.
+ *
+ * @param sg
+ * @param wholewidth
+ */
+ public void expandColSelection(SequenceGroup sg, boolean wholewidth)
+ {
+ int sgs, sge;
+ if (sg != null && (sgs = sg.getStartRes()) >= 0
+ && sg.getStartRes() <= (sge = sg.getEndRes())
+ && !this.hasSelectedColumns())
+ {
+ if (!wholewidth && alignment.getWidth() == (1 + sge - sgs))
+ {
+ // do nothing
+ return;
+ }
+ if (colSel == null)
+ {
+ colSel = new ColumnSelection();
+ }
+ for (int cspos = sg.getStartRes(); cspos <= sg.getEndRes(); cspos++)
+ {
+ colSel.addElement(cspos);
+ }
+ }
+ }
+
+ /**
+ * hold status of current selection group - defined on alignment or not.
+ */
+ private boolean selectionIsDefinedGroup = false;
+
+ @Override
+ public boolean isSelectionDefinedGroup()
+ {
+ if (selectionGroup == null)
+ {
+ return false;
+ }
+ if (isSelectionGroupChanged(true))
+ {
+ selectionIsDefinedGroup = false;
+ List<SequenceGroup> gps = alignment.getGroups();
+ if (gps == null || gps.size() == 0)
+ {
+ selectionIsDefinedGroup = false;
+ }
+ else
+ {
+ selectionIsDefinedGroup = gps.contains(selectionGroup);
+ }
+ }
+ return selectionGroup.isDefined() || selectionIsDefinedGroup;
+ }
+
+ /**
+ * null, or currently highlighted results on this view
+ */
+ private SearchResultsI searchResults = null;
+
+ protected TreeModel currentTree = null;
+
+ @Override
+ public boolean hasSearchResults()
+ {
+ return searchResults != null;
+ }
+
+ @Override
+ public void setSearchResults(SearchResultsI results)
+ {
+ searchResults = results;
+ }
+
+ @Override
+ public SearchResultsI getSearchResults()
+ {
+ return searchResults;
+ }
+
+ /**
+ * get the consensus sequence as displayed under the PID consensus annotation
+ * row.
+ *
+ * @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);
+ }
+ }
+
+ @Override
+ public Iterator<int[]> getViewAsVisibleContigs(boolean selectedRegionOnly)
+ {
+ int start = 0;
+ int end = 0;
+ if (selectedRegionOnly && selectionGroup != null)
+ {
+ start = selectionGroup.getStartRes();
+ end = selectionGroup.getEndRes() + 1;
+ }
+ else
+ {
+ end = alignment.getWidth();
+ }
+ return (alignment.getHiddenColumns().getVisContigsIterator(start, end,
+ false));
+ }
+ /**
+ * 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 });
+ }
+ }
+ }
+
+ /**
+ * Notify TreePanel and AlignmentPanel of some sort of alignment change.
+ */
+ public void notifyAlignment()
+ {
+ changeSupport.firePropertyChange(PROPERTY_ALIGNMENT, null, alignment.getSequences());
+ }
+
+ /**
+ * Notify AlignmentPanel of a sequence column selection or visibility changes.
+ */
+ public void notifySequence()
+ {
+ changeSupport.firePropertyChange(PROPERTY_SEQUENCE, null, null);
+ }
}