cd6490e59b9360fa3852b20b30520b15eb171a9f
[jalview.git] / src / jalview / datamodel / HiddenMarkovModel.java
1 package jalview.datamodel;
2
3 import java.util.ArrayList;
4 import java.util.HashMap;
5 import java.util.List;
6 import java.util.Map;
7 import java.util.Scanner;
8
9 /**
10  * Data structure which stores a hidden Markov model. Currently contains file properties as well, not sure whether these should be transferred to the HMMFile class
11  * 
12  * @author TZVanaalten
13  * 
14  */
15 public class HiddenMarkovModel
16 {
17   // Stores file properties. Do not directly access this field as it contains
18   // only string value - use the getter methods. For example, to find the length
19   // of theHMM, use getModelLength()to return an int value
20   Map<String, String> fileProperties = new HashMap<>();
21   
22   //contains all of the symbols used in this model. The index of each symbol represents its lookup value 
23   List<Character> symbols = new ArrayList<>();
24
25   // contains information for each node in the model. The begin node is at index
26   // 0. Node 0 contains average emission probabilities for each symbol
27   List<HMMNode> nodes = new ArrayList<>();
28
29   final String YES = "yes";
30
31   final String NO = "no";
32
33   int numberOfSymbols;
34   
35   //keys for file properties hashmap
36   private final String NAME = "NAME";
37
38   private final String ACCESSION_NUMBER = "ACC";
39
40   private final String DESCRIPTION = "DESC";
41
42   private final String LENGTH = "LENG";
43
44   private final String MAX_LENGTH = "MAXL";
45
46   private final String ALPHABET = "ALPH";
47
48   private final String DATE = "DATE";
49
50   private final String COMMAND_LOG = "COM";
51
52   private final String NUMBER_OF_SEQUENCES = "NSEQ";
53
54   private final String EFF_NUMBER_OF_SEQUENCES = "EFFN";
55
56   private final String CHECK_SUM = "CKSUM";
57
58   private final String GATHERING_THRESHOLDS = "GA";
59
60   private final String TRUSTED_CUTOFFS = "TC";
61
62   private final String NOISE_CUTOFFS = "NC";
63
64   private final String STATISTICS = "STATS";
65
66   private final String COMPO = "COMPO";
67   
68   private final String GATHERING_THRESHOLD = "GA";
69
70   private final String TRUSTED_CUTOFF = "TC";
71
72   private final String NOISE_CUTOFF = "NC";
73
74   private final String VITERBI = "VITERBI";
75
76   private final String MSV = "MSV";
77
78   private final String FORWARD = "FORWARD";
79
80   private final String MAP = "MAP";
81
82   private final String REFERENCE_ANNOTATION = "RF";
83
84   private final String CONSENSUS_RESIDUE = "CONS";
85
86   private final String CONSENSUS_STRUCTURE = "CS";
87
88   private final String MASKED_VALUE = "MM";
89   
90   final static String[] TRANSITION_TYPES = new String[] { "m->m", "m->i",
91       "m->d", "i->m", "i->i", "d->m", "d->d" };
92
93   public String getTransitionType(int index)
94   {
95     return TRANSITION_TYPES[index];
96   }
97
98   public String[] getTransitionTypes()
99   {
100     return TRANSITION_TYPES;
101   }
102   public char getSymbol(int index)
103   {
104     return getSymbols().get(index);
105   }
106   public Map<String, String> getFileProperties()
107   {
108     return fileProperties;
109   }
110
111   public HMMNode getNode(int nodeIndex)
112   {
113     return getNodes().get(nodeIndex);
114   }
115
116   public void setSymbols(List<Character> symbolsL)
117   {
118     this.symbols = symbolsL;
119   }
120
121   public String getName()
122   {
123     return fileProperties.get(NAME);
124   }
125   public String getAccessionNumber()
126   {
127     return fileProperties.get(ACCESSION_NUMBER);
128   }
129
130   public void setAccessionNumber(String value)
131   {
132     fileProperties.put(ACCESSION_NUMBER, value);
133   }
134
135   public String getDescription()
136   {
137     return fileProperties.get(DESCRIPTION);
138   }
139
140   public void setDescription(String value)
141   {
142     fileProperties.put(DESCRIPTION, value);
143   }
144
145   public Integer getLength()
146   {
147     if (fileProperties.get(LENGTH) == null)
148     {
149       return null;
150     }
151     return Integer.parseInt(fileProperties.get(LENGTH));
152   }
153
154   public void setLength(int value)
155   {
156     fileProperties.put(LENGTH, String.valueOf(value));
157   }
158
159   public Integer getMaxInstanceLength()
160   {
161     if (fileProperties.get(MAX_LENGTH) == null)
162     {
163       return null;
164     }
165     return Integer.parseInt(fileProperties.get(MAX_LENGTH));
166   }
167
168   public void setMaxInstanceLength(int value)
169   {
170     fileProperties.put(MAX_LENGTH, String.valueOf(value));
171   }
172
173   // gets type of symbol alphabet - "amino", "DNA", "RNA"
174   public String getAlphabetType()
175   {
176     return fileProperties.get(ALPHABET);
177   }
178
179   public void setAlphabetType(String value)
180   {
181     fileProperties.put(ALPHABET, value);
182   }
183
184   // not sure whether to implement this with Date object
185   public String getDate()
186   {
187     return fileProperties.get(DATE);
188   }
189
190   public void setDate(String value)
191   {
192     fileProperties.put(DATE, value);
193   }
194
195   // not sure whether to implement this
196   public String getCommandLineLog()
197   {
198     return fileProperties.get(COMMAND_LOG);
199   }
200
201   public void setCommandLineLog(String value)
202   {
203     fileProperties.put(COMMAND_LOG, value);
204   }
205
206   // gets the number of sequences that the HMM was trained on
207   public Integer getNumberOfSequences()
208   {
209     if (fileProperties.get(NUMBER_OF_SEQUENCES) == null)
210     {
211       return null;
212     }
213     return Integer.parseInt(fileProperties.get(NUMBER_OF_SEQUENCES));
214   }
215
216   public void setNumberOfSequences(int value)
217   {
218     fileProperties.put(NUMBER_OF_SEQUENCES, String.valueOf(value));
219   }
220
221   // gets the effective number determined during sequence weighting
222   public Double getEffectiveNumberOfSequences()
223   {
224     if (fileProperties.get(LENGTH) == null)
225     {
226       return null;
227     }
228     return Double.parseDouble(fileProperties.get(EFF_NUMBER_OF_SEQUENCES));
229   }
230
231   public void setEffectiveNumberOfSequences(double value)
232   {
233     fileProperties.put(EFF_NUMBER_OF_SEQUENCES, String.valueOf(value));
234   }
235
236   public Long getCheckSum()
237   {
238     if (fileProperties.get(LENGTH) == null)
239     {
240       return null;
241     }
242     return Long.parseLong(fileProperties.get(CHECK_SUM));
243   }
244
245   public void setCheckSum(long value)
246   {
247     fileProperties.put(CHECK_SUM, String.valueOf(value));
248   }
249
250   public List<HMMNode> getNodes()
251   {
252     return nodes;
253   }
254
255   public void setNodes(List<HMMNode> nodes)
256   {
257     this.nodes = nodes;
258   }
259   
260   /**
261    * gets the match emission at a node for a symbol
262    * @param nodeIndex
263    * position of node in model
264    * @param symbolIndex
265    * index of symbol being searched
266    * @return
267    * negative log probability of a match emission of the given symbol
268    */
269   public double getMatchEmission(int nodeIndex, int symbolIndex)
270   {
271     double value = nodes.get(nodeIndex).getMatchEmissions().get(symbolIndex);
272     return value;
273   }
274   
275   /**
276    * gets the insert emission at a node for a symbol
277    * @param nodeIndex
278    * position of node in model
279    * @param symbolIndex
280    * index of symbol being searched
281    * @return
282    * negative log probability of an insert emission of the given symbol
283    */
284   public double getInsertEmission(int nodeIndex, int symbolIndex)
285   {
286     double value = nodes.get(nodeIndex).getInsertEmissions().get(symbolIndex);
287     return value;
288   }
289   
290   /**
291    * gets the state transition at a node for a specific transition
292    * @param nodeIndex
293    * position of node in model
294    * @param transitionIndex
295    * index of stransition being searched
296    * @return
297    * negative log probability of a state transition of the given type
298    */
299   public double getStateTransition(int nodeIndex, int transitionIndex)
300   {
301     double value = nodes.get(nodeIndex).getStateTransitions()
302             .get(transitionIndex);
303     return value;
304   }
305   
306   public Integer getNodeAlignmentColumn(int nodeIndex)
307   {
308     Integer value = nodes.get(nodeIndex).getAlignmentColumn();
309    return value;
310   }
311   
312   public char getConsensusResidue(int nodeIndex)
313   {
314    char value = nodes.get(nodeIndex).getConsensusResidue();
315    return value;
316   }
317   
318   public char getReferenceAnnotation(int nodeIndex)
319   {
320    char value = nodes.get(nodeIndex).getReferenceAnnotation();
321    return value;
322   }
323   
324   public char getMaskedValue(int nodeIndex)
325   {
326    char value = nodes.get(nodeIndex).getMaskValue();
327    return value;
328   }
329   
330   public char getConsensusStructure(int nodeIndex)
331   {
332    char value = nodes.get(nodeIndex).getConsensusStructure();
333    return value;
334   }
335   
336   /**
337    * returns the average match emission for a given symbol
338    * @param symbolIndex
339    * index of symbol
340    * @return
341    * average negative log propbability of a match emission of the given symbol
342    */
343   public double getAverageMatchEmission(int symbolIndex)
344   {
345     double value = nodes.get(0).getMatchEmissions().get(symbolIndex);
346     return value;
347   }
348
349   public int getNumberOfSymbols()
350   {
351     return numberOfSymbols;
352   }
353
354   public void setNumberOfSymbols(int numberOfSymbols)
355   {
356     this.numberOfSymbols = numberOfSymbols;
357   }
358
359   public List<Character> getSymbols()
360   {
361     return symbols;
362   }
363
364
365   /**
366    * fills symbol array and also finds numberOfSymbols
367    * 
368    * @param parser
369    *          scanner scanning symbol line in file
370    */
371   public void fillSymbols(Scanner parser)
372   {
373     while (parser.hasNext())
374     {
375       String strSymbol = parser.next();
376       char[] symbol = strSymbol.toCharArray();
377       symbols.add(symbol[0]);
378     }
379     numberOfSymbols = symbols.size();
380   }
381
382   /**
383    * adds file property
384    * 
385    * @param key
386    * @param value
387    */
388   public void addFileProperty(String key, String value)
389   {
390     fileProperties.put(key, value);
391   }
392
393   public boolean referenceAnnotationIsActive()
394   {
395     String status;
396     status = fileProperties.get(REFERENCE_ANNOTATION);
397     if (status == null)
398     {
399       return false;
400     }
401     switch (status)
402     {
403     case YES:
404       return true;
405     case NO:
406       return false;
407     default:
408       return false;
409     }
410
411   }
412
413   public boolean maskValueIsActive()
414   {
415     String status;
416     status = fileProperties.get(MASKED_VALUE);
417     if (status == null)
418     {
419       return false;
420     }
421     switch (status)
422     {
423     case YES:
424       return true;
425     case NO:
426       return false;
427     default:
428       return false;
429     }
430
431   }
432
433   public boolean consensusResidueIsActive()
434   {
435     String status;
436     status = fileProperties.get(CONSENSUS_RESIDUE);
437     if (status == null)
438     {
439       return false;
440     }
441     switch (status)
442     {
443     case YES:
444       return true;
445     case NO:
446       return false;
447     default:
448       return false;
449     }
450
451   }
452
453   public boolean consensusStructureIsActive()
454   {
455     String status;
456     status = fileProperties.get(CONSENSUS_STRUCTURE);
457     if (status == null)
458     {
459       return false;
460     }
461     switch (status)
462     {
463     case YES:
464       return true;
465     case NO:
466       return false;
467     default:
468       return false;
469     }
470
471   }
472
473   public boolean mapIsActive()
474   {
475     String status;
476     status = fileProperties.get(MAP);
477     if (status == null)
478     {
479       return false;
480     }
481     switch (status)
482     {
483     case YES:
484       return true;
485     case NO:
486       return false;
487     default:
488       return false;
489     }
490
491   }
492
493   public void setAlignmentColumn(int nodeIndex, int column)
494   {
495     nodes.get(nodeIndex).setAlignmentColumn(column);
496   }
497
498   public void setReferenceAnnotation(int nodeIndex, char value)
499   {
500     nodes.get(nodeIndex).setReferenceAnnotation(value);
501   }
502
503   public void setConsensusResidue(int nodeIndex, char value)
504   {
505     nodes.get(nodeIndex).setConsensusResidue(value);
506   }
507
508   public void setConsensusStructure(int nodeIndex, char value)
509   {
510     nodes.get(nodeIndex).setConsensusStructure(value);
511   }
512
513   public void setMaskValue(int nodeIndex, char value)
514   {
515     nodes.get(nodeIndex).setMaskValue(value);
516   }
517
518   public String getGatheringThreshold()
519   {
520     String value;
521     value = fileProperties.get("GA");
522     return value;
523   }
524
525   public String getNoiseCutoff()
526   {
527     String value;
528     value = fileProperties.get("NC");
529     return value;
530   }
531
532   public String getTrustedCutoff()
533   {
534     String value;
535     value = fileProperties.get("TC");
536     return value;
537   }
538
539   public String getViterbi()
540   {
541     String value;
542     value = fileProperties.get(VITERBI);
543     return value;
544   }
545
546   public String getMSV()
547   {
548     String value;
549     value = fileProperties.get(MSV);
550     return value;
551   }
552
553   public String getForward()
554   {
555     String value;
556     value = fileProperties.get(FORWARD);
557     return value;
558   }
559
560   public void setMAPStatus(boolean status)
561   {
562     if (status == true)
563     {
564       fileProperties.put(MAP, YES);
565     }
566     else
567     {
568       fileProperties.put(MAP, NO);
569     }
570   }
571
572   public void setReferenceAnnotationStatus(boolean status)
573   {
574     if (status == true)
575     {
576       fileProperties.put(REFERENCE_ANNOTATION, YES);
577     }
578     else
579     {
580       fileProperties.put(REFERENCE_ANNOTATION, NO);
581     }
582   }
583
584   public void setMaskedValueStatus(boolean status)
585   {
586     if (status == true)
587     {
588       fileProperties.put(MASKED_VALUE, YES);
589     }
590     else
591     {
592       fileProperties.put(MASKED_VALUE, NO);
593     }
594   }
595
596   public void setConsensusResidueStatus(boolean status)
597   {
598     if (status == true)
599     {
600       fileProperties.put(CONSENSUS_RESIDUE, YES);
601     }
602     else
603     {
604       fileProperties.put(CONSENSUS_RESIDUE, NO);
605     }
606   }
607
608   public void setConsensusStructureStatus(boolean status)
609   {
610     if (status == true)
611     {
612       fileProperties.put(CONSENSUS_STRUCTURE, YES);
613     }
614     else
615     {
616       fileProperties.put(CONSENSUS_STRUCTURE, NO);
617     }
618   }
619 }
620