1 package jalview.schemes;
3 import jalview.api.AlignViewportI;
4 import jalview.datamodel.AnnotatedCollectionI;
5 import jalview.datamodel.HiddenMarkovModel;
6 import jalview.datamodel.SequenceI;
7 import jalview.util.ColorUtils;
8 import jalview.util.Comparison;
10 import java.awt.Color;
11 import java.io.BufferedReader;
12 import java.io.FileNotFoundException;
13 import java.io.FileReader;
14 import java.io.IOException;
15 import java.util.ArrayList;
16 import java.util.HashMap;
17 import java.util.List;
23 public class HMMMatchScoreColourScheme extends ResidueColourScheme
26 private Map<Character, Map<Integer, Map<String, Double>>> probabilities;
28 private List<Integer> ranges;
30 private static double binSize;
32 public class MatchProbReader
34 private BufferedReader reader;
36 MatchProbReader() throws FileNotFoundException
38 reader = new BufferedReader(
39 new FileReader("resources/ProbabilityOfMatch"));
43 public Map<Character, Map<String, Double>> getProbabilities() throws IOException
45 Map<Character, Map<String, Double>> probabilities = new HashMap<>();
47 String[] alphabet = reader.readLine().split("\\,");
48 for (int i = 1; i < alphabet.length - 1; i++)
50 probabilities.put(alphabet[i].replaceAll("\\ ", "").charAt(0),
54 String line = reader.readLine();
57 String[] contents = line.split("\\,");
59 for(int i = 1; i < contents.length; i++)
61 probabilities.get(alphabet[i].replaceAll("\\ ", "").charAt(0))
62 .put(contents[0], Double
63 .valueOf(contents[i].replaceAll("\\ ", "")));
65 line = reader.readLine();
73 public Map<Character, Map<Integer, Map<String, Double>>> getProbabilities()
77 Map<Character, Map<Integer, Map<String, Double>>> probabilities = new HashMap<>();
79 ranges = new ArrayList<>();
82 binSize = Double.valueOf((reader.readLine().replaceAll("\\ ", "")));
83 String line = reader.readLine();
84 char c = line.charAt(0);
88 line = reader.readLine();
89 while (line != null && line.split("\\,").length != 1)
91 String[] llrs = line.split("\\,");
92 String[] counts = reader.readLine().split("\\,");
93 int range = Integer.valueOf(llrs[0]);
95 if (!ranges.contains(range))
99 if (!probabilities.containsKey(c))
101 probabilities.put(c, new HashMap<>());
103 probabilities.get(c).put(range, new HashMap<>());
105 for (int i = 1; i < llrs.length; i++)
107 probabilities.get(c).get(range).put(
108 llrs[i].replaceAll("\\ ", ""),
109 Double.valueOf(counts[i].replaceAll("\\ ", "")));
112 line = reader.readLine();
120 return probabilities;
125 private static final Color INSERTION_COLOUR = Color.white;
128 * the aligned HMM consensus sequence to use as reference for colouring
130 private SequenceI hmmSeq;
132 private HiddenMarkovModel hmm;
134 private Map<Character, Float> frequencies;
137 * Constructor given a list of Hidden Markov Model consensus sequences. The
138 * first sequence provides the HMM profile from which we can read the emission
139 * probabilities that determine the colour.
142 * @throws IOException
144 public HMMMatchScoreColourScheme(List<SequenceI> hmmSeqs)
146 hmmSeq = hmmSeqs.isEmpty() ? null : hmmSeqs.get(0);
147 hmm = hmmSeq == null ? null : hmmSeq.getHMM();
151 MatchProbReader probabilityReader = new MatchProbReader();
152 probabilities = probabilityReader.getProbabilities();
153 } catch (IOException e)
155 System.out.println(e.getStackTrace());
160 * Default constructor (required by ColourSchemes.loadColourSchemes)
162 public HMMMatchScoreColourScheme()
167 public Color findColour(char symbol, int column, SequenceI seq,
168 String consensusResidue, float pid)
174 return findColour(symbol, column, seq.gapMap().length);
177 // TODO change documentation
179 * Returns the colour at a particular symbol at a column in the alignment:
181 * <li>white for a gap</li>
182 * <li>red for an insertion</li>
183 * <li>orange for negative information content</li>
184 * <li>white to blue for increasing information content</li>
191 private Color findColour(char symbol, int column, int length)
193 if (getHmm() == null || Comparison.isGap(symbol))
197 if (Comparison.isGap(hmmSeq.getCharAt(column)))
199 return INSERTION_COLOUR;
201 if (Character.isLowerCase(symbol))
203 symbol = Character.toUpperCase(symbol);
207 if (hmm.getBackgroundFrequencies().containsKey(symbol))
209 int lengthBin = getLengthBin(length);
212 .log(getHmm().getMatchEmissionProbability(column, symbol)
213 / hmm.getBackgroundFrequencies().get(symbol));
215 if (!probabilities.get(symbol).get(lengthBin)
216 .containsKey(format(llr)))
222 prob = probabilities.get(symbol).get(lengthBin).get(format(llr));
226 return new Color(140, 140, 140);
229 Color colour = Color.ORANGE;
233 colour = ColorUtils.getGraduatedColour((float) prob, 0.5f,
239 colour = ColorUtils.getGraduatedColour((float) prob, 0f, Color.red,
246 public static String format(Double d)
248 String formatArg = String.valueOf(binSize);
250 // if bin size, need format "%.n" where n is number of decimal places
253 formatArg = "." + formatArg.split("\\.")[1].length();
256 Double rounded = Math.round(d / binSize) * binSize;
257 String formatted = String.format("%" + formatArg + "f", rounded);
259 // format sometimes returns a number rounded to 0 as -0
260 // this ensures output will always be 0
261 if (Double.valueOf(formatted) == 0)
270 * Answers the maximum possible value of information score (log ratio), for use
271 * in scaling a graduated colour range
275 protected float getMaxInformationScore()
281 * Answers a new colour scheme instance based on the HMM of the first sequence
282 * in ac that has an HMM
285 public ColourSchemeI getInstance(AlignViewportI viewport,
286 AnnotatedCollectionI ac)
288 return newInstance(ac);
292 * Constructor given a sequence collection
296 public HMMMatchScoreColourScheme(AnnotatedCollectionI ac)
298 this(ac.getHmmSequences());
302 * Answers a new instance of the colour scheme for the given HMM
307 protected HMMMatchScoreColourScheme newInstance(AnnotatedCollectionI ac)
309 return new HMMMatchScoreColourScheme(ac);
313 public boolean isSimple()
319 * Answers true if the sequence collection has an HMM consensus sequence and
320 * that the first HMM sequence contains background frequencies, else false
323 public boolean isApplicableTo(AnnotatedCollectionI ac)
325 return !ac.getHmmSequences().isEmpty() && ac.getHmmSequences().get(0)
326 .getHMM().getBackgroundFrequencies() != null;
329 protected Map<Character, Float> getFrequencies()
334 protected void setFrequencies(Map<Character, Float> frequencies)
336 this.frequencies = frequencies;
339 protected HiddenMarkovModel getHmm()
344 protected SequenceI getHmmSequence()
350 public String getSchemeName()
352 return JalviewColourScheme.HMMMatchScore.toString();
355 private int getLengthBin(int l)
357 for (int i = 1; i < ranges.size(); i++)
359 if (l >= ranges.get(i - 1) && l < ranges.get(i))
361 return ranges.get(i);