import jalview.analysis.AAFrequency;
import jalview.analysis.Conservation;
-import jalview.schemes.CollectionColourScheme;
-import jalview.schemes.CollectionColourSchemeI;
+import jalview.renderer.ResidueShader;
+import jalview.renderer.ResidueShaderI;
import jalview.schemes.ColourSchemeI;
+import jalview.util.MessageManager;
import java.awt.Color;
import java.util.ArrayList;
boolean colourText = false;
/**
+ * True if the group is defined as a group on the alignment, false if it is
+ * just a selection.
+ */
+ boolean isDefined = false;
+
+ /**
* after Olivier's non-conserved only character display
*/
boolean showNonconserved = false;
/**
* group members
*/
- private List<SequenceI> sequences = new ArrayList<SequenceI>();
+ private List<SequenceI> sequences = new ArrayList<>();
/**
* representative sequence for this group (if any)
/**
* Colourscheme applied to group if any
*/
- public CollectionColourSchemeI cs;
+ public ResidueShaderI cs;
// start column (base 0)
int startRes = 0;
*/
private boolean ignoreGapsInConsensus = true;
+ private boolean ignoreBelowBackground = true;
+
+ private boolean infoLetterHeight = false;
+
/**
* consensus calculation property
*/
*/
private boolean normaliseSequenceLogo;
- /**
- * @return the includeAllConsSymbols
+ /*
+ * visibility of rows or represented rows covered by group
*/
- public boolean isShowSequenceLogo()
- {
- return showSequenceLogo;
- }
+ private boolean hidereps = false;
+
+ /*
+ * visibility of columns intersecting this group
+ */
+ private boolean hidecols = false;
+
+ AlignmentAnnotation consensus = null;
+
+ AlignmentAnnotation conservation = null;
+
+ AlignmentAnnotation information = null;
+
+ private boolean showConsensusHistogram;
+
+ private AnnotatedCollectionI context;
+
+ private boolean showHMMSequenceLogo;
+
+ private boolean normaliseHMMSequenceLogo;
+
+ private boolean showInformationHistogram;
/**
* Creates a new SequenceGroup object.
public SequenceGroup()
{
groupName = "JGroup:" + this.hashCode();
- cs = new CollectionColourScheme();
+ cs = new ResidueShader();
}
/**
this.displayBoxes = displayBoxes;
this.displayText = displayText;
this.colourText = colourText;
- this.cs = new CollectionColourScheme(scheme);
+ this.cs = new ResidueShader(scheme);
startRes = start;
endRes = end;
recalcConservation();
this();
if (seqsel != null)
{
- sequences = new ArrayList<SequenceI>();
+ sequences = new ArrayList<>();
sequences.addAll(seqsel.sequences);
if (seqsel.groupName != null)
{
colourText = seqsel.colourText;
startRes = seqsel.startRes;
endRes = seqsel.endRes;
- cs = seqsel.cs;
+ cs = new ResidueShader((ResidueShader) seqsel.cs);
if (seqsel.description != null)
{
description = new String(seqsel.description);
}
hidecols = seqsel.hidecols;
hidereps = seqsel.hidereps;
+ showNonconserved = seqsel.showNonconserved;
+ showSequenceLogo = seqsel.showSequenceLogo;
+ normaliseSequenceLogo = seqsel.normaliseSequenceLogo;
+ showConsensusHistogram = seqsel.showConsensusHistogram;
+ showHMMSequenceLogo = seqsel.showHMMSequenceLogo;
+ normaliseHMMSequenceLogo = seqsel.normaliseHMMSequenceLogo;
+ showInformationHistogram = seqsel.showInformationHistogram;
idColour = seqsel.idColour;
outlineColour = seqsel.outlineColour;
seqrep = seqsel.seqrep;
thresholdTextColour = seqsel.thresholdTextColour;
width = seqsel.width;
ignoreGapsInConsensus = seqsel.ignoreGapsInConsensus;
+ ignoreBelowBackground = seqsel.ignoreBelowBackground;
+ infoLetterHeight = seqsel.infoLetterHeight;
if (seqsel.conserve != null)
{
recalcConservation(); // safer than
}
}
+ public boolean isShowSequenceLogo()
+ {
+ return showSequenceLogo;
+ }
+
public SequenceI[] getSelectionAsNewSequences(AlignmentI align)
{
int iSize = sequences.size();
}
else
{
- List<SequenceI> allSequences = new ArrayList<SequenceI>();
+ List<SequenceI> allSequences = new ArrayList<>();
for (SequenceI seq : sequences)
{
allSequences.add(seq);
*/
public boolean recalcConservation(boolean defer)
{
- if (cs == null && consensus == null && conservation == null)
+ if (cs == null && consensus == null && conservation == null
+ && information == null)
{
return false;
}
{
ProfilesI cnsns = AAFrequency.calculate(sequences, startRes,
endRes + 1, showSequenceLogo);
+ if (information != null)
+ {
+ HiddenMarkovModel hmm = information.sequenceRef.getHMM();
+
+ ProfilesI info = AAFrequency.calculateHMMProfiles(hmm,
+ (endRes + 1) - startRes, startRes, endRes + 1,
+ showHMMSequenceLogo, ignoreBelowBackground,
+ infoLetterHeight);
+ _updateInformationRow(info, sequences.size());
+ upd = true;
+ }
if (consensus != null)
{
_updateConsensusRow(cnsns, sequences.size());
conservation.description = "Conservation for group " + getName()
+ " less than " + consPercGaps + "% gaps";
// preserve width if already set
- int aWidth = (conservation.annotations != null) ? (endRes < conservation.annotations.length ? conservation.annotations.length
- : endRes + 1)
+ int aWidth = (conservation.annotations != null)
+ ? (endRes < conservation.annotations.length
+ ? conservation.annotations.length
+ : endRes + 1)
: endRes + 1;
conservation.annotations = null;
conservation.annotations = new Annotation[aWidth]; // should be alignment
public ProfilesI consensusData = null;
+ public ProfilesI informationData = null;
+
private void _updateConsensusRow(ProfilesI cnsns, long nseq)
{
if (consensus == null)
consensus.description = "Percent Identity";
consensusData = cnsns;
// preserve width if already set
- int aWidth = (consensus.annotations != null) ? (endRes < consensus.annotations.length ? consensus.annotations.length
- : endRes + 1)
+ int aWidth = (consensus.annotations != null)
+ ? (endRes < consensus.annotations.length
+ ? consensus.annotations.length
+ : endRes + 1)
: endRes + 1;
consensus.annotations = null;
consensus.annotations = new Annotation[aWidth]; // should be alignment width
}
/**
+ * Recalculates the information content on the HMM annotation.
+ *
+ * @param cnsns
+ * @param nseq
+ */
+ private void _updateInformationRow(ProfilesI cnsns, long nseq)
+ {
+ if (information == null)
+ {
+ getInformation();
+ }
+ information.description = MessageManager
+ .getString("label.information_description");
+ informationData = cnsns;
+ // preserve width if already set
+ int aWidth = (information.annotations != null)
+ ? (endRes < information.annotations.length
+ ? information.annotations.length : endRes + 1)
+ : endRes + 1;
+ information.annotations = null;
+ information.annotations = new Annotation[aWidth]; // should be alignment
+ // width
+ information.calcId = "HMM";
+ AAFrequency.completeInformation(information, cnsns, startRes,
+ endRes + 1, nseq, 0f); // TODO:
+ // setting
+ // container
+ // for
+ // ignoreGapsInInformationCalculation);
+ }
+
+ /**
* @param s
* sequence to either add or remove from group
* @param recalc
}
/**
- * visibility of rows or represented rows covered by group
- */
- private boolean hidereps = false;
-
- /**
* set visibility of sequences covered by (if no sequence representative is
* defined) or represented by this group.
*
}
/**
- * visibility of columns intersecting this group
- */
- private boolean hidecols = false;
-
- /**
* set intended visibility of columns covered by this group
*
* @param visibility
{
SequenceGroup sgroup = new SequenceGroup(this);
SequenceI[] insect = getSequencesInOrder(alignment);
- sgroup.sequences = new ArrayList<SequenceI>();
+ sgroup.sequences = new ArrayList<>();
for (int s = 0; insect != null && s < insect.length; s++)
{
if (map == null || map.containsKey(insect[s]))
this.showNonconserved = displayNonconserved;
}
- AlignmentAnnotation consensus = null, conservation = null;
-
- /**
- * flag indicating if consensus histogram should be rendered
- */
- private boolean showConsensusHistogram;
-
/**
* set this alignmentAnnotation object as the one used to render consensus
* annotation
}
/**
+ *
+ * @return information content annotation.
+ */
+ public AlignmentAnnotation getInformation()
+ {
+ // TODO get or calculate and get information annotation row for this group
+ int aWidth = this.getWidth();
+ // pointer
+ // possibility
+ // here.
+ if (aWidth < 0)
+ {
+ return null;
+ }
+ if (information == null)
+ {
+ information = new AlignmentAnnotation("", "", new Annotation[1], 0f,
+ 6.25f, AlignmentAnnotation.BAR_GRAPH);
+ information.hasText = true;
+ information.autoCalculated = false;
+ information.groupRef = this;
+ information.label = getName();
+ information.description = "Information content, measured in bits";
+ information.calcId = "HMM";
+ }
+ return information;
+ }
+
+ /**
* set this alignmentAnnotation object as the one used to render consensus
* annotation
*
return ignoreGapsInConsensus;
}
+ public void setIgnoreBelowBackground(boolean state)
+ {
+ if (this.ignoreBelowBackground != state)
+ {
+ ignoreBelowBackground = state;
+ }
+ ignoreBelowBackground = state;
+ }
+
+ public boolean getIgnoreBelowBackground()
+ {
+ return ignoreBelowBackground;
+ }
+
+ public void setInfoLetterHeight(boolean state)
+ {
+ if (this.infoLetterHeight != state)
+ {
+ infoLetterHeight = state;
+ }
+ infoLetterHeight = state;
+ }
+
+ public boolean getInfoLetterHeight()
+ {
+ return infoLetterHeight;
+ }
+
/**
* @param showSequenceLogo
* indicates if a sequence logo is shown for consensus annotation
{
// TODO add in other methods like 'getAlignmentAnnotation(String label),
// etc'
- ArrayList<AlignmentAnnotation> annot = new ArrayList<AlignmentAnnotation>();
+ ArrayList<AlignmentAnnotation> annot = new ArrayList<>();
synchronized (sequences)
{
for (SequenceI seq : sequences)
@Override
public Iterable<AlignmentAnnotation> findAnnotation(String calcId)
{
- List<AlignmentAnnotation> aa = new ArrayList<AlignmentAnnotation>();
+ List<AlignmentAnnotation> aa = new ArrayList<>();
if (calcId == null)
{
return aa;
return aa;
}
- /**
- * Returns a list of annotations that match the specified sequenceRef, calcId
- * and label, ignoring null values.
- *
- * @return list of AlignmentAnnotation objects
- */
@Override
public Iterable<AlignmentAnnotation> findAnnotations(SequenceI seq,
String calcId, String label)
{
- ArrayList<AlignmentAnnotation> aa = new ArrayList<AlignmentAnnotation>();
+ ArrayList<AlignmentAnnotation> aa = new ArrayList<>();
for (AlignmentAnnotation ann : getAlignmentAnnotation())
{
- if (ann.getCalcId() != null && ann.getCalcId().equals(calcId)
- && ann.sequenceRef != null && ann.sequenceRef == seq
- && ann.label != null && ann.label.equals(label))
+ if ((calcId == null || (ann.getCalcId() != null
+ && ann.getCalcId().equals(calcId)))
+ && (seq == null || (ann.sequenceRef != null
+ && ann.sequenceRef == seq))
+ && (label == null
+ || (ann.label != null && ann.label.equals(label))))
{
aa.add(ann);
}
}
}
- private AnnotatedCollectionI context;
+ /**
+ * Sets the alignment or group context for this group, and whether it is
+ * defined as a group
+ *
+ * @param ctx
+ * the context for the group
+ * @param defined
+ * whether the group is defined on the alignment or is just a
+ * selection
+ * @throws IllegalArgumentException
+ * if setting the context would result in a circular reference chain
+ */
+ public void setContext(AnnotatedCollectionI ctx, boolean defined)
+ {
+ setContext(ctx);
+ this.isDefined = defined;
+ }
/**
- * set the alignment or group context for this group
+ * Sets the alignment or group context for this group
*
- * @param context
+ * @param ctx
+ * the context for the group
+ * @throws IllegalArgumentException
+ * if setting the context would result in a circular reference chain
*/
- public void setContext(AnnotatedCollectionI context)
+ public void setContext(AnnotatedCollectionI ctx)
{
- this.context = context;
+ AnnotatedCollectionI ref = ctx;
+ while (ref != null)
+ {
+ if (ref == this || ref.getContext() == ctx)
+ {
+ throw new IllegalArgumentException(
+ "Circular reference in SequenceGroup.context");
+ }
+ ref = ref.getContext();
+ }
+ this.context = ctx;
}
/*
return context;
}
+ public boolean isDefined()
+ {
+ return isDefined;
+ }
+
public void setColourScheme(ColourSchemeI scheme)
{
if (cs == null)
{
- cs = new CollectionColourScheme();
+ cs = new ResidueShader();
}
cs.setColourScheme(scheme);
}
- public void setGroupColourScheme(CollectionColourSchemeI scheme)
+ public void setGroupColourScheme(ResidueShaderI scheme)
{
cs = scheme;
}
return cs == null ? null : cs.getColourScheme();
}
- public CollectionColourSchemeI getGroupColourScheme()
+ public ResidueShaderI getGroupColourScheme()
{
return cs;
}
+
+ @Override
+ public boolean isNucleotide()
+ {
+ if (context != null)
+ {
+ return context.isNucleotide();
+ }
+ return false;
+ }
+
+ /**
+ * @param seq
+ * @return true if seq is a member of the group
+ */
+
+ public boolean contains(SequenceI seq1)
+ {
+ return sequences.contains(seq1);
+ }
+
+ /**
+ * @param seq
+ * @param apos
+ * @return true if startRes<=apos and endRes>=apos and seq is in the group
+ */
+ public boolean contains(SequenceI seq, int apos)
+ {
+ return (startRes <= apos && endRes >= apos) && sequences.contains(seq);
+ }
+
+ public boolean isShowInformationHistogram()
+ {
+ return showInformationHistogram;
+ }
+
+ public void setShowInformationHistogram(boolean state)
+ {
+ if (showInformationHistogram != state && information != null)
+ {
+ this.showInformationHistogram = state;
+ // recalcConservation(); TODO don't know what to do here next
+ }
+ this.showInformationHistogram = state;
+
+ }
+
+ public boolean isShowHMMSequenceLogo()
+ {
+ // TODO Auto-generated method stub
+ return showHMMSequenceLogo;
+ }
+
+ public void setshowHMMSequenceLogo(boolean state)
+ {
+ showHMMSequenceLogo = state;
+
+ }
+
+ public boolean isNormaliseHMMSequenceLogo()
+ {
+ // TODO Auto-generated method stub
+ return normaliseHMMSequenceLogo;
+ }
+
+ public void setNormaliseHMMSequenceLogo(boolean state)
+ {
+ normaliseSequenceLogo = state;
+ }
+
+ /**
+ * Returns all HMM consensus sequences. This will not return real sequences
+ * with HMMs. If remove is set to true, the consensus sequences will be
+ * removed from the alignment.
+ */
+ @Override // TODO make this more efficient.
+ public List<SequenceI> getHMMConsensusSequences(boolean remove)
+ {
+ List<SequenceI> seqs = new ArrayList<>();
+ int position = 0;
+ int seqsRemoved = 0;
+ boolean endReached = false;
+
+ while (!endReached)
+ {
+ SequenceI seq = sequences.get(position);
+ if (seq.isHMMConsensusSequence())
+ {
+ if (remove)
+ {
+ sequences.remove(position);
+ seqsRemoved++;
+ seq.setPreviousPosition(seqsRemoved + position - 1);
+ }
+ else
+ {
+ position++;
+ }
+ seqs.add(seq);
+ }
+ else
+ {
+ position++;
+ }
+
+ if (position >= sequences.size())
+ {
+ endReached = true;
+ }
+ }
+ return seqs;
+ }
+
}