* @param endCol
* end column (exclusive)
* @param ignoreGaps
- * if true, normalise residue percentages
+ * if true, normalise residue percentages
* @param showSequenceLogo
* if true include all information symbols, else just show modal
* residue
- * @param nseq
- * number of sequences
*/
public static float completeInformation(AlignmentAnnotation information,
- ProfilesI profiles, int startCol, int endCol, long nseq,
- float currentMax)
+ ProfilesI profiles, int startCol, int endCol)
{
// long now = System.currentTimeMillis();
- if (information == null || information.annotations == null
- || information.annotations.length < endCol)
+ if (information == null || information.annotations == null)
{
/*
* called with a bad alignment annotation row
float max = 0f;
SequenceI hmmSeq = information.sequenceRef;
+
+ int seqLength = hmmSeq.getLength();
+ if (information.annotations.length < seqLength)
+ {
+ return 0;
+ }
+
HiddenMarkovModel hmm = hmmSeq.getHMM();
for (int column = startCol; column < endCol; column++)
{
+ if (column >= seqLength)
+ {
+ // hmm consensus sequence is shorter than the alignment
+ break;
+ }
ProfileI profile = profiles.get(column);
if (profile == null)
{
description, ' ', value);
}
- max = Math.max(max, currentMax);
information.graphMax = max;
return max;
}
annot.hasText = false;
if (calcId != null)
{
- annot.setCalcId(new String(calcId));
+ annot.setCalcId(calcId);
}
annot.autoCalculated = autoCalc;
if (seqRef != null)
* - null or specific sequence reference
* @param groupRef
* - null or specific group reference
- * @param method
- * - CalcId for the annotation (must match)
*
* @return existing annotation matching the given attributes
*/
(endRes + 1) - startRes, startRes, endRes + 1,
showHMMSequenceLogo, hmmIgnoreBelowBackground,
hmmUseInfoLetterHeight);
- _updateInformationRow(info, sequences.size());
+ _updateInformationRow(info);
upd = true;
}
if (consensus != null)
}
/**
- * Recalculates the information content on the HMM annotation.
+ * Recalculates the information content on the HMM annotation
*
* @param cnsns
- * @param nseq
*/
- private void _updateInformationRow(ProfilesI cnsns, long nseq)
+ private void _updateInformationRow(ProfilesI cnsns)
{
if (hmmInformation == null)
{
// width
hmmInformation.setCalcId(InformationThread.HMM_CALC_ID);
AAFrequency.completeInformation(hmmInformation, cnsns, startRes,
- endRes + 1, nseq, 0f);
+ endRes + 1);
}
/**
package jalview.hmmer;
import jalview.api.AlignViewportI;
+import jalview.bin.Cache;
import jalview.datamodel.Alignment;
-import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.AnnotatedCollectionI;
import jalview.datamodel.SequenceGroup;
import jalview.io.FileParse;
import jalview.io.HMMFile;
import jalview.util.MessageManager;
-import jalview.workers.InformationThread;
import jalview.ws.params.ArgumentI;
import java.io.File;
@Override
public void run()
{
+ if (params == null)
+ {
+ Cache.log.error("No parameters to HMMBuild!|");
+ return;
+ }
+
long msgID = System.currentTimeMillis();
af.setProgressBar(MessageManager.getString("status.running_hmmbuild"),
msgID);
AlignViewportI viewport = af.getViewport();
try
{
- List<AnnotatedCollectionI> runBuildFor = new ArrayList<>();
- if (params != null)
- {
- for (ArgumentI arg : params)
- {
- String name = arg.getName();
- if (MessageManager.getString("label.hmmbuild_for").equals(name))
- {
- String value = arg.getValue();
- if (MessageManager.getString("label.alignment")
- .equals(value))
- {
- runBuildFor.add(alignment);
- }
- else if (MessageManager.getString("label.groups_and_alignment")
- .equals(value))
- {
- runBuildFor.add(alignment);
- runBuildFor.addAll(viewport.getAlignment().getGroups());
- }
- else if (MessageManager.getString("label.groups").equals(value))
- {
- runBuildFor.addAll(viewport.getAlignment().getGroups());
- }
- else if (MessageManager.getString("label.selected_group")
- .equals(value))
- {
- runBuildFor.add(viewport.getSelectionGroup());
- }
- }
- else if (MessageManager.getString("label.use_reference")
- .equals(name))
- {
- // todo disable this option if no RF annotation on alignment
- if (!af.getViewport().hasReferenceAnnotation())
- {
- JvOptionPane.showInternalMessageDialog(af, MessageManager
- .getString("warn.no_reference_annotation"));
- // return;
- }
- }
- }
- }
-
/*
* run hmmbuild for alignment and/or groups as selected
*/
+ List<AnnotatedCollectionI> runBuildFor = parseParameters(viewport);
+
for (AnnotatedCollectionI grp : runBuildFor)
{
runHMMBuild(grp);
}
/**
+ * Scans the parameters to determine whether to run hmmmbuild for the whole
+ * alignment or specified subgroup(s) or both
+ *
+ * @param viewport
+ * @return
+ */
+ protected List<AnnotatedCollectionI> parseParameters(
+ AlignViewportI viewport)
+ {
+ List<AnnotatedCollectionI> runBuildFor = new ArrayList<>();
+ for (ArgumentI arg : params)
+ {
+ String name = arg.getName();
+ if (MessageManager.getString("label.hmmbuild_for").equals(name))
+ {
+ String value = arg.getValue();
+ if (MessageManager.getString("label.alignment").equals(value))
+ {
+ runBuildFor.add(alignment);
+ }
+ else if (MessageManager.getString("label.groups_and_alignment")
+ .equals(value))
+ {
+ runBuildFor.add(alignment);
+ runBuildFor.addAll(viewport.getAlignment().getGroups());
+ }
+ else if (MessageManager.getString("label.groups").equals(value))
+ {
+ runBuildFor.addAll(viewport.getAlignment().getGroups());
+ }
+ else if (MessageManager.getString("label.selected_group")
+ .equals(value))
+ {
+ runBuildFor.add(viewport.getSelectionGroup());
+ }
+ }
+ else if (MessageManager.getString("label.use_reference")
+ .equals(name))
+ {
+ // todo disable this option if no RF annotation on alignment
+ if (!af.getViewport().hasReferenceAnnotation())
+ {
+ JvOptionPane.showInternalMessageDialog(af, MessageManager
+ .getString("warn.no_reference_annotation"));
+ // return;
+ }
+ }
+ }
+ return runBuildFor;
+ }
+
+ /**
* Runs hmmbuild on the given sequences (alignment or group)
*
* @param grp
/*
* copy over sequences, excluding hmm consensus sequences
- * hmm sequences and their Information annotation are also deleted
- * in preparation for re-adding them when recalculated
+ * hmm sequences are also deleted in preparation for
+ * re-adding them when recalculated; Information annotation is not
+ * deleted, it will be updated to reference the new hmm sequence
+ * by InformationThread.findOrCreateAnnotation
*/
Iterator<SequenceI> it = copy.iterator();
while (it.hasNext())
SequenceI seq = it.next();
if (seq.isHMMConsensusSequence())
{
- // todo leave it to InformationThread to delete annotations?
- AlignmentAnnotation[] seqAnnotations = seq
- .getAnnotation();
- if (seqAnnotations != null)
- {
- for (AlignmentAnnotation ann : seqAnnotations)
- {
- if (InformationThread.HMM_CALC_ID.equals(ann.getCalcId()))
- {
- alignment.deleteAnnotation(ann);
- }
- }
- }
alignment.deleteSequence(seq);
it.remove();
}
{
colourScheme = cs;
}
-
- @Override
- public void setInformation(ProfilesI info)
- {
- // TODO Auto-generated method stub
-
- }
}
* This file is part of Jalview.
*
* Jalview is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
+ * modify it under the terms of the GNU General License
* as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* Jalview is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
+ * PURPOSE. See the GNU General License for more details.
*
- * You should have received a copy of the GNU General Public License
+ * You should have received a copy of the GNU General License
* along with Jalview. If not, see <http://www.gnu.org/licenses/>.
* The Jalview Authors are detailed in the 'AUTHORS' file.
*/
public interface ResidueShaderI
{
+ void setConsensus(ProfilesI cons);
- public abstract void setConsensus(ProfilesI cons);
+ boolean conservationApplied();
- public abstract void setInformation(ProfilesI info);
+ void setConservationApplied(boolean conservationApplied);
- public abstract boolean conservationApplied();
+ void setConservation(Conservation cons);
- public abstract void setConservationApplied(boolean conservationApplied);
-
- public abstract void setConservation(Conservation cons);
-
- public abstract void alignmentChanged(AnnotatedCollectionI alignment,
+ void alignmentChanged(AnnotatedCollectionI alignment,
Map<SequenceI, SequenceCollectionI> hiddenReps);
/**
* @param consensusThreshold
* @param ignoreGaps
*/
- public abstract void setThreshold(int consensusThreshold,
+ void setThreshold(int consensusThreshold,
boolean ignoreGaps);
- public abstract void setConservationInc(int i);
+ void setConservationInc(int i);
- public abstract int getConservationInc();
+ int getConservationInc();
/**
* Get the percentage threshold for this colour scheme
*
* @return Returns the percentage threshold
*/
- public abstract int getThreshold();
+ int getThreshold();
/**
* Returns the possibly context dependent colour for the given symbol at the
* @param seq
* @return
*/
- public abstract Color findColour(char symbol, int position,
+ Color findColour(char symbol, int position,
SequenceI seq);
- public abstract ColourSchemeI getColourScheme();
+ ColourSchemeI getColourScheme();
- public abstract void setColourScheme(ColourSchemeI cs);
+ void setColourScheme(ColourSchemeI cs);
}
\ No newline at end of file
import jalview.datamodel.ProfilesI;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
-import jalview.renderer.ResidueShaderI;
import jalview.util.MessageManager;
import java.util.List;
return;
}
- eraseAnnotations(alignment);
computeProfiles(alignment);
- updateResultAnnotation(true);
+ updateAnnotation();
if (ap != null)
{
}
/**
- * Deletes any existing information annotations. These are sequence-related
- * annotations which relate to HMM consensus sequences for either the
- * alignment or a subgroup.
- *
- * @param alignment
- */
- protected void eraseAnnotations(AlignmentI alignment)
- {
- Iterable<AlignmentAnnotation> anns = alignment
- .findAnnotation(HMM_CALC_ID);
- for (AlignmentAnnotation ann : anns)
- {
- alignment.deleteAnnotation(ann);
- }
- }
-
- /**
* Computes HMM profiles for any HMM consensus sequences (for alignment or
- * subgroups)
+ * subgroups). Any alignment profile computed is stored on the viewport, any
+ * group profile computed is stored on the respective sequence group.
*
* @param alignment
+ * @see AlignViewportI#setHmmProfiles(ProfilesI)
*/
protected void computeProfiles(AlignmentI alignment)
{
0, width, true, alignViewport.isIgnoreBelowBackground(),
alignViewport.isInfoLetterHeight());
alignViewport.setHmmProfiles(hmmProfiles);
- // setColourSchemeInformation(hmmProfiles);
}
/*
0, width, true, group.isIgnoreBelowBackground(),
group.isUseInfoLetterHeight());
group.setHmmProfiles(hmmProfiles);
- // setColourSchemeInformation(hmmProfiles);
}
}
}
return alignViewport.getAlignment().getSequencesArray();
}
- protected void setColourSchemeInformation(ProfilesI information)
- {
- ResidueShaderI cs = alignViewport.getResidueShading();
- if (cs != null)
- {
- cs.setInformation(information);
- }
- }
-
/**
* Get the Gap annotation for the alignment
*
}
/**
- * Updates the information annotation from the sequence profile data using
- * current visualisation settings
+ * Computes Information Content annotation for any HMM consensus sequences
+ * (for alignment or groups), and updates (or adds) the annotation to the
+ * sequence and the alignment
*/
@Override
public void updateAnnotation()
{
- updateResultAnnotation(false);
- }
-
- /**
- * Constructs Information Content annotation for any HMM consensus sequences
- * (for alignment or groups), and adds the annotation to the sequence and the
- * alignment
- *
- * @param immediate
- */
- public void updateResultAnnotation(boolean immediate)
- {
AlignmentI alignment = alignViewport.getAlignment();
+ this.max = 0f;
+
/*
* annotation for alignment HMM consensus if present
*/
SequenceI hmmSeq = alignment.getHmmConsensus();
ProfilesI profile = alignViewport.getHmmProfiles();
- AlignmentAnnotation ann = makeInformationAnnotation(hmmSeq, profile);
- if (ann != null)
- {
- alignment.addAnnotation(ann);
- }
+ updateInformationAnnotation(hmmSeq, profile, null);
/*
* annotation for group HMM consensus if present
{
hmmSeq = group.getHmmConsensus();
ProfilesI profiles = group.getHmmProfiles();
- ann = makeInformationAnnotation(hmmSeq, profiles);
- if (ann != null)
- {
- ann.groupRef = group;
- alignment.addAnnotation(ann);
- }
+ updateInformationAnnotation(hmmSeq, profiles, group);
}
+
+ /*
+ * todo: this.max is not used, but acquires the maximum value of
+ * information in any of the annotations; set this as graphMax in all
+ * annotations to have them all scaled the same
+ */
}
/**
- * Constructs an HMM Profile information content annotation for a sequence
+ * Updates (and first constructs if necessary) an HMM Profile information
+ * content annotation for a sequence. The <code>group</code> argument is null
+ * for the whole alignment annotation, not null for a subgroup annotation.
*
* @param seq
* @param profile
+ * @param group
* @return
*/
- protected AlignmentAnnotation makeInformationAnnotation(SequenceI seq,
- ProfilesI profile)
+ protected AlignmentAnnotation updateInformationAnnotation(SequenceI seq,
+ ProfilesI profile, SequenceGroup group)
{
if (seq == null || profile == null)
{
return null;
}
- AlignmentI alignment = alignViewport.getAlignment();
- int aWidth = alignment == null ? 0 : alignment.getWidth();
- AlignmentAnnotation ann = new AlignmentAnnotation(seq.getName(),
- MessageManager.getString("label.information_description"),
- new Annotation[aWidth], 0f, 6.52f,
- AlignmentAnnotation.BAR_GRAPH);
- ann.hasText = true;
- ann.autoCalculated = false;
- ann.sequenceRef = seq;
- ann.setCalcId(InformationThread.HMM_CALC_ID);
+ AlignmentAnnotation ann = findOrCreateAnnotation(seq, group);
+
seq.addAlignmentAnnotation(ann);
- long nseq = getSequences().length;
max = AAFrequency.completeInformation(ann, profile,
- profile.getStartColumn(), profile.getEndColumn() + 1, nseq,
- max);
+ profile.getStartColumn(), profile.getEndColumn() + 1);
return ann;
}
/**
- * Convert the computed information data into the desired annotation for
- * display.
+ * A helper method that first searches for the HMM annotation that matches the
+ * group reference (null for the whole alignment annotation). If found, its
+ * sequence reference is updated to the given sequence (the recomputed HMM
+ * consensus sequence). If not found, it is created. This supports both
+ * creating the annotation the first time hmmbuild is run, and updating it if
+ * hmmbuild is re-run.
*
- * @param informationAnnotation
- * the annotation to be populated
- * @param hinformation
- * the computed information data
+ * @param seq
+ * @param group
+ * @return
*/
- protected void deriveInformation(
- AlignmentAnnotation informationAnnotation, ProfilesI hinformation)
+ AlignmentAnnotation findOrCreateAnnotation(SequenceI seq,
+ SequenceGroup group)
{
- long nseq = getSequences().length;
- max = AAFrequency.completeInformation(informationAnnotation,
- hinformation, hinformation.getStartColumn(),
- hinformation.getEndColumn() + 1, nseq, max);
+ /*
+ * can't use Alignment.findOrCreateAnnotation here because we
+ * want to update, rather than match on, the sequence ref
+ */
+ AlignmentAnnotation info = null;
+
+ AlignmentI alignment = alignViewport.getAlignment();
+ AlignmentAnnotation[] anns = alignment.getAlignmentAnnotation();
+ if (anns != null)
+ {
+ for (AlignmentAnnotation ann : anns)
+ {
+ if (HMM_CALC_ID.equals(ann.getCalcId()) && group == ann.groupRef)
+ {
+ info = ann;
+ info.setSequenceRef(seq);
+ break;
+ }
+ }
+ }
+
+ if (info == null)
+ {
+ int aWidth = alignment.getWidth();
+ String desc = MessageManager
+ .getString("label.information_description");
+ float graphMax = 6.52f; // todo where does this value derive from?
+ info = new AlignmentAnnotation(seq.getName(), desc,
+ new Annotation[aWidth], 0f, graphMax,
+ AlignmentAnnotation.BAR_GRAPH);
+ info.setCalcId(HMM_CALC_ID);
+ info.setSequenceRef(seq);
+ info.groupRef = group;
+ info.hasText = true;
+ alignment.addAnnotation(info);
+ }
+
+ return info;
}
}
seq.setHMM(hmm);
AlignmentAnnotation annot = new AlignmentAnnotation("", "", annots);
annot.setSequenceRef(seq);
- AAFrequency.completeInformation(annot, profs, 0, 1, 1, 1f);
+ AAFrequency.completeInformation(annot, profs, 0, 1);
float ic = annot.annotations[0].value;
assertEquals(0.91532f, ic, 0.0001f);
ic = annot.annotations[1].value;