From: tva Date: Fri, 28 Jun 2019 12:33:04 +0000 (+0100) Subject: JAL-2629 add file that should have been in previous commit X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=7040f8bdc8ab176e9b8e396dbce254b17eebeb7b;p=jalview.git JAL-2629 add file that should have been in previous commit --- diff --git a/src/jalview/schemes/HMMMatchScoreColourScheme.java b/src/jalview/schemes/HMMMatchScoreColourScheme.java new file mode 100644 index 0000000..36f66d0 --- /dev/null +++ b/src/jalview/schemes/HMMMatchScoreColourScheme.java @@ -0,0 +1,265 @@ +package jalview.schemes; + +import jalview.api.AlignViewportI; +import jalview.datamodel.AnnotatedCollectionI; +import jalview.datamodel.HiddenMarkovModel; +import jalview.datamodel.SequenceI; +import jalview.util.ColorUtils; +import jalview.util.Comparison; + +import java.awt.Color; +import java.io.BufferedReader; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +public class HMMMatchScoreColourScheme extends ResidueColourScheme +{ + + private Map> probabilities; + + public class MatchProbReader + { + private BufferedReader reader; + + MatchProbReader() throws FileNotFoundException + { + reader = new BufferedReader( + new FileReader("resources/ProbabilityOfMatch")); + } + + public Map> getProbabilities() throws IOException + { + Map> probabilities = new HashMap<>(); + + String[] alphabet = reader.readLine().split("\\,"); + for (int i = 1; i < alphabet.length - 1; i++) + { + probabilities.put(alphabet[i].replaceAll("\\ ", "").charAt(0), + new HashMap<>()); + } + + String line = reader.readLine(); + while(line != null) + { + String[] contents = line.split("\\,"); + + for(int i = 1; i < contents.length; i++) + { + probabilities.get(alphabet[i].replaceAll("\\ ", "").charAt(0)) + .put(contents[0], Double + .valueOf(contents[i].replaceAll("\\ ", ""))); + } + line = reader.readLine(); + + } + reader.close(); + return probabilities; + } + + + } + + private static final Color INSERTION_COLOUR = Color.white; + + /* + * the aligned HMM consensus sequence to use as reference for colouring + */ + private SequenceI hmmSeq; + + private HiddenMarkovModel hmm; + + private Map frequencies; + + /** + * Constructor given a list of Hidden Markov Model consensus sequences. The + * first sequence provides the HMM profile from which we can read the emission + * probabilities that determine the colour. + * + * @param hmmSeqs + * @throws IOException + */ + public HMMMatchScoreColourScheme(List hmmSeqs) + { + hmmSeq = hmmSeqs.isEmpty() ? null : hmmSeqs.get(0); + hmm = hmmSeq == null ? null : hmmSeq.getHMM(); + + try + { + MatchProbReader probabilityReader = new MatchProbReader(); + probabilities = probabilityReader.getProbabilities(); + } catch (IOException e) + { + System.out.println(e.getStackTrace()); + } + } + + /** + * Default constructor (required by ColourSchemes.loadColourSchemes) + */ + public HMMMatchScoreColourScheme() + { + } + + @Override + public Color findColour(char symbol, int column, SequenceI seq, + String consensusResidue, float pid) + { + return findColour(symbol, column); + } + + // TODO change + /** + * Returns the colour at a particular symbol at a column in the alignment: + *
    + *
  • white for a gap
  • + *
  • red for an insertion
  • + *
  • orange for negative information content
  • + *
  • white to blue for increasing information content
  • + *
+ * + * @param symbol + * @param column + * @return + */ + private Color findColour(char symbol, int column) + { + if (getHmm() == null || Comparison.isGap(symbol)) + { + return Color.white; + } + if (Comparison.isGap(hmmSeq.getCharAt(column))) + { + return INSERTION_COLOUR; + } + if (Character.isLowerCase(symbol)) + { + symbol = Character.toUpperCase(symbol); + } + + double llr = Math + .log(getHmm().getMatchEmissionProbability(column, symbol) + / hmm.getBackgroundFrequencies().get(symbol)); + + double prob = probabilities.get(symbol).get(format(llr)); + + Color colour = Color.ORANGE; + if (prob >= 0.5) + { + + colour = ColorUtils.getGraduatedColour((float) prob, 0.5f, + Color.WHITE, 1f, + Color.blue); + } + else + { + colour = ColorUtils.getGraduatedColour((float) prob, 0f, Color.red, + 0.5f, Color.WHITE); + } + + return colour; + } + + public static String format(Double d) + { + String formatted = String.format("%.1f", d); + if (Double.valueOf(formatted) == 0) + { + formatted = "0"; + } + return formatted; + } + + /** + * Answers the maximum possible value of information score (log ratio), for use + * in scaling a graduated colour range + * + * @return + */ + protected float getMaxInformationScore() + { + return 0f; + } + + /** + * Answers a new colour scheme instance based on the HMM of the first sequence + * in ac that has an HMM + */ + @Override + public ColourSchemeI getInstance(AlignViewportI viewport, + AnnotatedCollectionI ac) + { + return newInstance(ac); + } + + /** + * Constructor given a sequence collection + * + * @param ac + */ + public HMMMatchScoreColourScheme(AnnotatedCollectionI ac) + { + this(ac.getHmmSequences()); + } + + /** + * Answers a new instance of the colour scheme for the given HMM + * + * @param ac + * @return + */ + protected HMMMatchScoreColourScheme newInstance(AnnotatedCollectionI ac) + { + return new HMMMatchScoreColourScheme(ac); + } + + @Override + public boolean isSimple() + { + return false; + } + + /** + * Answers true if the sequence collection has an HMM consensus sequence, else + * false + */ + @Override + public boolean isApplicableTo(AnnotatedCollectionI ac) + { + return !ac.getHmmSequences().isEmpty(); + } + + protected Map getFrequencies() + { + return frequencies; + } + + protected void setFrequencies(Map frequencies) + { + this.frequencies = frequencies; + } + + protected HiddenMarkovModel getHmm() + { + return hmm; + } + + protected SequenceI getHmmSequence() + { + return hmmSeq; + } + + @Override + public String getSchemeName() + { + return JalviewColourScheme.HMMMatchScore.toString(); + } + + +} + +