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.renderer.ResidueShaderI;
14 import jalview.util.MessageManager;
16 import java.util.List;
19 * This class calculates HMM Information Content annotations, based on any HMM
20 * consensus sequences and their HMM models. HMM consensus sequences may be
21 * present for the whole alignment, or subgroups of it.
24 public class InformationThread extends AlignCalcWorker
26 public static final String HMM_CALC_ID = "HMM";
28 private float max = 0f;
33 * @param alignViewport
36 public InformationThread(AlignViewportI alignViewport,
37 AlignmentViewPanel alignPanel)
39 super(alignViewport, alignPanel);
43 * Recomputes Information annotations for any HMM consensus sequences (for
44 * alignment and/or groups)
49 if (calcMan.isPending(this))
53 calcMan.notifyStart(this);
54 // long started = System.currentTimeMillis();
58 if (calcMan.isPending(this))
60 // another instance of this is waiting to run
61 calcMan.workerComplete(this);
64 while (!calcMan.notifyWorking(this))
66 // another thread in progress, wait my turn
71 ap.paintAlignment(false, false);
74 } catch (Exception ex)
79 if (alignViewport.isClosed())
84 AlignmentI alignment = alignViewport.getAlignment();
86 int aWidth = alignment == null ? -1 : alignment.getWidth();
90 calcMan.workerComplete(this);
94 eraseAnnotations(alignment);
95 computeProfiles(alignment);
96 updateResultAnnotation(true);
100 ap.adjustAnnotationHeight();
101 ap.paintAlignment(true, true);
103 } catch (OutOfMemoryError error)
105 calcMan.disableWorker(this);
106 ap.raiseOOMWarning("calculating information", error);
109 calcMan.workerComplete(this);
114 * Deletes any existing information annotations. These are sequence-related
115 * annotations which relate to HMM consensus sequences for either the
116 * alignment or a subgroup.
120 protected void eraseAnnotations(AlignmentI alignment)
122 Iterable<AlignmentAnnotation> anns = alignment
123 .findAnnotation(HMM_CALC_ID);
124 for (AlignmentAnnotation ann : anns)
126 alignment.deleteAnnotation(ann);
131 * Computes HMM profiles for any HMM consensus sequences (for alignment or
136 protected void computeProfiles(AlignmentI alignment)
138 int width = alignment.getWidth();
141 * alignment HMM profile
143 SequenceI seq = alignment.getHmmConsensus();
146 HiddenMarkovModel hmm = seq.getHMM();
147 ProfilesI hmmProfiles = AAFrequency.calculateHMMProfiles(hmm, width,
148 0, width, true, alignViewport.isIgnoreBelowBackground(),
149 alignViewport.isInfoLetterHeight());
150 alignViewport.setHmmProfiles(hmmProfiles);
151 // setColourSchemeInformation(hmmProfiles);
157 List<SequenceGroup> groups = alignment.getGroups();
158 for (SequenceGroup group : groups)
160 seq = group.getHmmConsensus();
163 HiddenMarkovModel hmm = seq.getHMM();
164 ProfilesI hmmProfiles = AAFrequency.calculateHMMProfiles(hmm, width,
165 0, width, true, group.isIgnoreBelowBackground(),
166 group.isUseInfoLetterHeight());
167 group.setHmmProfiles(hmmProfiles);
168 // setColourSchemeInformation(hmmProfiles);
174 * gets the sequences on the alignment on the viewport.
178 protected SequenceI[] getSequences()
180 return alignViewport.getAlignment().getSequencesArray();
183 protected void setColourSchemeInformation(ProfilesI information)
185 ResidueShaderI cs = alignViewport.getResidueShading();
188 cs.setInformation(information);
193 * Get the Gap annotation for the alignment
197 protected AlignmentAnnotation getGapAnnotation()
199 return alignViewport.getOccupancyAnnotation();
203 * Updates the information annotation from the sequence profile data using
204 * current visualisation settings
207 public void updateAnnotation()
209 updateResultAnnotation(false);
213 * Constructs Information Content annotation for any HMM consensus sequences
214 * (for alignment or groups), and adds the annotation to the sequence and the
219 public void updateResultAnnotation(boolean immediate)
221 AlignmentI alignment = alignViewport.getAlignment();
224 * annotation for alignment HMM consensus if present
226 SequenceI hmmSeq = alignment.getHmmConsensus();
227 ProfilesI profile = alignViewport.getHmmProfiles();
228 AlignmentAnnotation ann = makeInformationAnnotation(hmmSeq, profile);
231 alignment.addAnnotation(ann);
235 * annotation for group HMM consensus if present
237 for (SequenceGroup group : alignment.getGroups())
239 hmmSeq = group.getHmmConsensus();
240 ProfilesI profiles = group.getHmmProfiles();
241 ann = makeInformationAnnotation(hmmSeq, profiles);
244 ann.groupRef = group;
245 alignment.addAnnotation(ann);
251 * Constructs an HMM Profile information content annotation for a sequence
257 protected AlignmentAnnotation makeInformationAnnotation(SequenceI seq,
260 if (seq == null || profile == null)
265 AlignmentI alignment = alignViewport.getAlignment();
266 int aWidth = alignment == null ? 0 : alignment.getWidth();
267 AlignmentAnnotation ann = new AlignmentAnnotation(seq.getName(),
268 MessageManager.getString("label.information_description"),
269 new Annotation[aWidth], 0f, 6.52f,
270 AlignmentAnnotation.BAR_GRAPH);
272 ann.autoCalculated = false;
273 ann.sequenceRef = seq;
274 ann.setCalcId(InformationThread.HMM_CALC_ID);
275 seq.addAlignmentAnnotation(ann);
277 long nseq = getSequences().length;
278 max = AAFrequency.completeInformation(ann, profile,
279 profile.getStartColumn(), profile.getEndColumn() + 1, nseq,
286 * Convert the computed information data into the desired annotation for
289 * @param informationAnnotation
290 * the annotation to be populated
291 * @param hinformation
292 * the computed information data
294 protected void deriveInformation(
295 AlignmentAnnotation informationAnnotation, ProfilesI hinformation)
297 long nseq = getSequences().length;
298 max = AAFrequency.completeInformation(informationAnnotation,
299 hinformation, hinformation.getStartColumn(),
300 hinformation.getEndColumn() + 1, nseq, max);