1 package jalview.workers;
3 import jalview.analysis.AAFrequency;
4 import jalview.api.AlignViewportI;
5 import jalview.api.AlignmentViewPanel;
6 import jalview.datamodel.AlignmentAnnotation;
7 import jalview.datamodel.AlignmentI;
8 import jalview.datamodel.Annotation;
9 import jalview.datamodel.HiddenMarkovModel;
10 import jalview.datamodel.ProfilesI;
11 import jalview.datamodel.SequenceGroup;
12 import jalview.datamodel.SequenceI;
13 import jalview.util.MessageManager;
15 import java.util.List;
18 * This class calculates HMM Information Content annotations, based on any HMM
19 * consensus sequences and their HMM models. HMM consensus sequences may be
20 * present for the whole alignment, or subgroups of it.
23 public class InformationThread extends AlignCalcWorker
25 public static final String HMM_CALC_ID = "HMM";
27 private float max = 0f;
32 * @param alignViewport
35 public InformationThread(AlignViewportI alignViewport,
36 AlignmentViewPanel alignPanel)
38 super(alignViewport, alignPanel);
42 * Recomputes Information annotations for any HMM consensus sequences (for
43 * alignment and/or groups)
48 if (calcMan.isPending(this))
52 calcMan.notifyStart(this);
53 // long started = System.currentTimeMillis();
57 if (calcMan.isPending(this))
59 // another instance of this is waiting to run
60 calcMan.workerComplete(this);
63 while (!calcMan.notifyWorking(this))
65 // another thread in progress, wait my turn
70 ap.paintAlignment(false, false);
73 } catch (Exception ex)
78 if (alignViewport.isClosed())
83 AlignmentI alignment = alignViewport.getAlignment();
85 int aWidth = alignment == null ? -1 : alignment.getWidth();
89 calcMan.workerComplete(this);
93 computeProfiles(alignment);
98 ap.adjustAnnotationHeight();
99 ap.paintAlignment(true, true);
101 } catch (OutOfMemoryError error)
103 calcMan.disableWorker(this);
104 ap.raiseOOMWarning("calculating information", error);
107 calcMan.workerComplete(this);
112 * Computes HMM profiles for any HMM consensus sequences (for alignment or
113 * subgroups). Any alignment profile computed is stored on the viewport, any
114 * group profile computed is stored on the respective sequence group.
117 * @see AlignViewportI#setHmmProfiles(ProfilesI)
119 protected void computeProfiles(AlignmentI alignment)
121 int width = alignment.getWidth();
124 * alignment HMM profile
126 SequenceI seq = alignment.getHmmConsensus();
129 HiddenMarkovModel hmm = seq.getHMM();
130 ProfilesI hmmProfiles = AAFrequency.calculateHMMProfiles(hmm, width,
131 0, width, true, alignViewport.isIgnoreBelowBackground(),
132 alignViewport.isInfoLetterHeight());
133 alignViewport.setHmmProfiles(hmmProfiles);
139 List<SequenceGroup> groups = alignment.getGroups();
140 for (SequenceGroup group : groups)
142 seq = group.getHmmConsensus();
145 HiddenMarkovModel hmm = seq.getHMM();
146 ProfilesI hmmProfiles = AAFrequency.calculateHMMProfiles(hmm, width,
147 0, width, true, group.isIgnoreBelowBackground(),
148 group.isUseInfoLetterHeight());
149 group.setHmmProfiles(hmmProfiles);
155 * gets the sequences on the alignment on the viewport.
159 protected SequenceI[] getSequences()
161 return alignViewport.getAlignment().getSequencesArray();
165 * Get the Gap annotation for the alignment
169 protected AlignmentAnnotation getGapAnnotation()
171 return alignViewport.getOccupancyAnnotation();
175 * Computes Information Content annotation for any HMM consensus sequences
176 * (for alignment or groups), and updates (or adds) the annotation to the
177 * sequence and the alignment
180 public void updateAnnotation()
182 AlignmentI alignment = alignViewport.getAlignment();
187 * annotation for alignment HMM consensus if present
189 SequenceI hmmSeq = alignment.getHmmConsensus();
190 ProfilesI profile = alignViewport.getHmmProfiles();
191 updateInformationAnnotation(hmmSeq, profile, null);
194 * annotation for group HMM consensus if present
196 for (SequenceGroup group : alignment.getGroups())
198 hmmSeq = group.getHmmConsensus();
199 ProfilesI profiles = group.getHmmProfiles();
200 updateInformationAnnotation(hmmSeq, profiles, group);
204 * todo: this.max is not used, but acquires the maximum value of
205 * information in any of the annotations; set this as graphMax in all
206 * annotations to have them all scaled the same
211 * Updates (and first constructs if necessary) an HMM Profile information
212 * content annotation for a sequence. The <code>group</code> argument is null
213 * for the whole alignment annotation, not null for a subgroup annotation.
220 protected AlignmentAnnotation updateInformationAnnotation(SequenceI seq,
221 ProfilesI profile, SequenceGroup group)
223 if (seq == null || profile == null)
228 AlignmentAnnotation ann = findOrCreateAnnotation(seq, group);
230 seq.addAlignmentAnnotation(ann);
232 max = AAFrequency.completeInformation(ann, profile,
233 profile.getStartColumn(), profile.getEndColumn() + 1);
239 * A helper method that first searches for the HMM annotation that matches the
240 * group reference (null for the whole alignment annotation). If found, its
241 * sequence reference is updated to the given sequence (the recomputed HMM
242 * consensus sequence). If not found, it is created. This supports both
243 * creating the annotation the first time hmmbuild is run, and updating it if
244 * hmmbuild is re-run.
250 AlignmentAnnotation findOrCreateAnnotation(SequenceI seq,
254 * can't use Alignment.findOrCreateAnnotation here because we
255 * want to update, rather than match on, the sequence ref
257 AlignmentAnnotation info = null;
259 AlignmentI alignment = alignViewport.getAlignment();
260 AlignmentAnnotation[] anns = alignment.getAlignmentAnnotation();
263 for (AlignmentAnnotation ann : anns)
265 if (HMM_CALC_ID.equals(ann.getCalcId()) && group == ann.groupRef)
268 info.setSequenceRef(seq);
276 int aWidth = alignment.getWidth();
277 String desc = MessageManager
278 .getString("label.information_description");
279 float graphMax = 6.52f; // todo where does this value derive from?
280 info = new AlignmentAnnotation(seq.getName(), desc,
281 new Annotation[aWidth], 0f, graphMax,
282 AlignmentAnnotation.BAR_GRAPH);
283 info.setCalcId(HMM_CALC_ID);
284 info.setSequenceRef(seq);
285 info.groupRef = group;
287 alignment.addAnnotation(info);