X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fdatamodel%2FHiddenMarkovModel.java;h=6b8b09562dcdc9011c9d910201630d068ed37c78;hb=bbc8fc127287ad3a11f0b470d37d741ddca162ff;hp=cd6490e59b9360fa3852b20b30520b15eb171a9f;hpb=a6eac8873a084ad41c392ec27566f23258b0d026;p=jalview.git diff --git a/src/jalview/datamodel/HiddenMarkovModel.java b/src/jalview/datamodel/HiddenMarkovModel.java index cd6490e..6b8b095 100644 --- a/src/jalview/datamodel/HiddenMarkovModel.java +++ b/src/jalview/datamodel/HiddenMarkovModel.java @@ -1,332 +1,454 @@ package jalview.datamodel; +import jalview.io.HMMFile; +import jalview.schemes.ResidueProperties; +import jalview.util.Comparison; +import jalview.util.MapList; + import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Scanner; /** - * 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 + * Data structure which stores a hidden Markov model * * @author TZVanaalten * */ public class HiddenMarkovModel { - // Stores file properties. Do not directly access this field as it contains - // only string value - use the getter methods. For example, to find the length - // of theHMM, use getModelLength()to return an int value - Map fileProperties = new HashMap<>(); - - //contains all of the symbols used in this model. The index of each symbol represents its lookup value - List symbols = new ArrayList<>(); - - // contains information for each node in the model. The begin node is at index - // 0. Node 0 contains average emission probabilities for each symbol - List nodes = new ArrayList<>(); - - final String YES = "yes"; - - final String NO = "no"; - - int numberOfSymbols; - - //keys for file properties hashmap - private final String NAME = "NAME"; - - private final String ACCESSION_NUMBER = "ACC"; - - private final String DESCRIPTION = "DESC"; - - private final String LENGTH = "LENG"; - - private final String MAX_LENGTH = "MAXL"; - - private final String ALPHABET = "ALPH"; - - private final String DATE = "DATE"; - - private final String COMMAND_LOG = "COM"; - - private final String NUMBER_OF_SEQUENCES = "NSEQ"; - - private final String EFF_NUMBER_OF_SEQUENCES = "EFFN"; - - private final String CHECK_SUM = "CKSUM"; - - private final String GATHERING_THRESHOLDS = "GA"; - - private final String TRUSTED_CUTOFFS = "TC"; - - private final String NOISE_CUTOFFS = "NC"; + private static final char GAP_DASH = '-'; - private final String STATISTICS = "STATS"; + public final static String YES = "yes"; - private final String COMPO = "COMPO"; - - private final String GATHERING_THRESHOLD = "GA"; + public final static String NO = "no"; - private final String TRUSTED_CUTOFF = "TC"; + public static final int MATCHTOMATCH = 0; - private final String NOISE_CUTOFF = "NC"; + public static final int MATCHTOINSERT = 1; - private final String VITERBI = "VITERBI"; + public static final int MATCHTODELETE = 2; - private final String MSV = "MSV"; + public static final int INSERTTOMATCH = 3; - private final String FORWARD = "FORWARD"; + public static final int INSERTTOINSERT = 4; - private final String MAP = "MAP"; + public static final int DELETETOMATCH = 5; - private final String REFERENCE_ANNOTATION = "RF"; + public static final int DELETETODELETE = 6; - private final String CONSENSUS_RESIDUE = "CONS"; + private static final double LOG2 = Math.log(2); - private final String CONSENSUS_STRUCTURE = "CS"; + /* + * properties read from HMM file header lines + */ + private Map fileProperties = new HashMap<>(); - private final String MASKED_VALUE = "MM"; + private String fileHeader; - final static String[] TRANSITION_TYPES = new String[] { "m->m", "m->i", - "m->d", "i->m", "i->i", "d->m", "d->d" }; - - public String getTransitionType(int index) - { - return TRANSITION_TYPES[index]; - } - - public String[] getTransitionTypes() - { - return TRANSITION_TYPES; - } - public char getSymbol(int index) - { - return getSymbols().get(index); - } - public Map getFileProperties() - { - return fileProperties; - } + /* + * the symbols used in this model e.g. "ACGT" + */ + private String alphabet; - public HMMNode getNode(int nodeIndex) - { - return getNodes().get(nodeIndex); - } + /* + * symbol lookup index into the alphabet for 'A' to 'Z' + */ + private int[] symbolIndexLookup = new int['Z' - 'A' + 1]; - public void setSymbols(List symbolsL) - { - this.symbols = symbolsL; - } + /* + * Nodes in the model. The begin node is at index 0, and contains + * average emission probabilities for each symbol. + */ + private List nodes = new ArrayList<>(); - public String getName() - { - return fileProperties.get(NAME); - } - public String getAccessionNumber() - { - return fileProperties.get(ACCESSION_NUMBER); - } + /* + * the aligned HMM consensus sequence extracted from the HMM profile + */ + private SequenceI hmmSeq; - public void setAccessionNumber(String value) - { - fileProperties.put(ACCESSION_NUMBER, value); - } + /* + * mapping from HMM nodes to residues of the hmm consensus sequence + */ + private Mapping mapToHmmConsensus; - public String getDescription() - { - return fileProperties.get(DESCRIPTION); - } + // stores background frequencies of alignment from which this model came + private Map backgroundFrequencies; - public void setDescription(String value) + /** + * Constructor + */ + public HiddenMarkovModel() { - fileProperties.put(DESCRIPTION, value); } - public Integer getLength() - { - if (fileProperties.get(LENGTH) == null) + /** + * Copy constructor given a new aligned sequence with which to associate the + * HMM profile + * + * @param hmm + * @param sq + */ + public HiddenMarkovModel(HiddenMarkovModel hmm, SequenceI sq) + { + super(); + this.fileProperties = new HashMap<>(hmm.fileProperties); + this.alphabet = hmm.alphabet; + this.nodes = new ArrayList<>(hmm.nodes); + this.symbolIndexLookup = hmm.symbolIndexLookup; + this.fileHeader = new String(hmm.fileHeader); + this.hmmSeq = sq; + this.backgroundFrequencies = hmm.getBackgroundFrequencies(); + if (sq.getDatasetSequence() == hmm.mapToHmmConsensus.getTo()) { - return null; + // same dataset sequence e.g. after realigning search results + this.mapToHmmConsensus = hmm.mapToHmmConsensus; + } + else + { + // different dataset sequence e.g. after loading HMM from project + this.mapToHmmConsensus = new Mapping(sq.getDatasetSequence(), + hmm.mapToHmmConsensus.getMap()); } - return Integer.parseInt(fileProperties.get(LENGTH)); } - public void setLength(int value) + /** + * Returns the information content at a specified column, calculated as the + * sum (over possible symbols) of the log ratio + * + *
+   *  log(emission probability / background probability) / log(2)
+   * 
+ * + * @param column + * column position (base 0) + * @return + */ + public float getInformationContent(int column) { - fileProperties.put(LENGTH, String.valueOf(value)); - } + float informationContent = 0f; - public Integer getMaxInstanceLength() - { - if (fileProperties.get(MAX_LENGTH) == null) + for (char symbol : getSymbols().toCharArray()) { - return null; + float freq = ResidueProperties.backgroundFrequencies + .get(getAlphabetType()).get(symbol); + float prob = (float) getMatchEmissionProbability(column, symbol); + informationContent += prob * Math.log(prob / freq); } - return Integer.parseInt(fileProperties.get(MAX_LENGTH)); + + informationContent = informationContent / (float) LOG2; + + return informationContent; } - public void setMaxInstanceLength(int value) + /** + * Gets the file header of the .hmm file this model came from + * + * @return + */ + public String getFileHeader() { - fileProperties.put(MAX_LENGTH, String.valueOf(value)); + return fileHeader; } - // gets type of symbol alphabet - "amino", "DNA", "RNA" - public String getAlphabetType() + /** + * Sets the file header of this model. + * + * @param header + */ + public void setFileHeader(String header) { - return fileProperties.get(ALPHABET); + fileHeader = header; } - public void setAlphabetType(String value) + /** + * Returns the symbols used in this hidden Markov model + * + * @return + */ + public String getSymbols() { - fileProperties.put(ALPHABET, value); + return alphabet; } - - // not sure whether to implement this with Date object - public String getDate() + + /** + * Gets the node in the hidden Markov model at the specified position. + * + * @param nodeIndex + * The index of the node requested. Node 0 optionally contains the + * average match emission probabilities across the entire model, and + * always contains the insert emission probabilities and state + * transition probabilities for the begin node. Node 1 contains the + * first node in the HMM that can correspond to a column in the + * alignment. + * @return + */ + public HMMNode getNode(int nodeIndex) { - return fileProperties.get(DATE); + return nodes.get(nodeIndex); } - public void setDate(String value) + /** + * Returns the name of the sequence alignment on which the HMM is based. + * + * @return + */ + public String getName() { - fileProperties.put(DATE, value); + return fileProperties.get(HMMFile.NAME); } - - // not sure whether to implement this - public String getCommandLineLog() + + /** + * Answers the string value of the property (parsed from an HMM file) for the + * given key, or null if the property is not present + * + * @param key + * @return + */ + public String getProperty(String key) { - return fileProperties.get(COMMAND_LOG); + return fileProperties.get(key); } - public void setCommandLineLog(String value) + /** + * Answers true if the property with the given key is present with a value of + * "yes" (not case-sensitive), else false + * + * @param key + * @return + */ + public boolean getBooleanProperty(String key) { - fileProperties.put(COMMAND_LOG, value); + return YES.equalsIgnoreCase(fileProperties.get(key)); } - // gets the number of sequences that the HMM was trained on - public Integer getNumberOfSequences() + /** + * Returns the length of the hidden Markov model. The value returned is the + * LENG property if specified, else the number of nodes, excluding the begin + * node (which should be the same thing). + * + * @return + */ + public int getLength() { - if (fileProperties.get(NUMBER_OF_SEQUENCES) == null) + if (fileProperties.get(HMMFile.LENGTH) == null) { - return null; + return nodes.size() - 1; // not counting BEGIN node } - return Integer.parseInt(fileProperties.get(NUMBER_OF_SEQUENCES)); + return Integer.parseInt(fileProperties.get(HMMFile.LENGTH)); } - public void setNumberOfSequences(int value) + /** + * Returns the value of mandatory property "ALPH" - "amino", "DNA", "RNA" are + * the options. Other alphabets may be added. + * + * @return + */ + public String getAlphabetType() { - fileProperties.put(NUMBER_OF_SEQUENCES, String.valueOf(value)); + return fileProperties.get(HMMFile.ALPHABET); } - // gets the effective number determined during sequence weighting - public Double getEffectiveNumberOfSequences() - { - if (fileProperties.get(LENGTH) == null) + /** + * Sets the model alphabet to the symbols in the given string (ignoring any + * whitespace), and returns the number of symbols + * + * @param symbols + */ + public int setAlphabet(String symbols) + { + String trimmed = symbols.toUpperCase().replaceAll("\\s", ""); + int count = trimmed.length(); + alphabet = trimmed; + symbolIndexLookup = new int['Z' - 'A' + 1]; + Arrays.fill(symbolIndexLookup, -1); + int ignored = 0; + + /* + * save the symbols in order, and a quick lookup of symbol position + */ + for (short i = 0; i < count; i++) { - return null; + char symbol = trimmed.charAt(i); + if (symbol >= 'A' && symbol <= 'Z' + && symbolIndexLookup[symbol - 'A'] == -1) + { + symbolIndexLookup[symbol - 'A'] = i; + } + else + { + System.err + .println( + "Unexpected or duplicated character in HMM ALPHabet: " + + symbol); + ignored++; + } } - return Double.parseDouble(fileProperties.get(EFF_NUMBER_OF_SEQUENCES)); - } - - public void setEffectiveNumberOfSequences(double value) - { - fileProperties.put(EFF_NUMBER_OF_SEQUENCES, String.valueOf(value)); + return count - ignored; } - public Long getCheckSum() + /** + * Answers the node of the model corresponding to an aligned column position + * (0...), or null if there is no such node + * + * @param column + * @return + */ + HMMNode getNodeForColumn(int column) { - if (fileProperties.get(LENGTH) == null) + /* + * if the hmm consensus is gapped at the column, + * there is no corresponding node + */ + if (Comparison.isGap(hmmSeq.getCharAt(column))) { return null; } - return Long.parseLong(fileProperties.get(CHECK_SUM)); - } - public void setCheckSum(long value) - { - fileProperties.put(CHECK_SUM, String.valueOf(value)); + /* + * find the node (if any) that is mapped to the + * consensus sequence residue position at the column + */ + int seqPos = hmmSeq.findPosition(column); + int[] nodeNo = mapToHmmConsensus.getMap().locateInFrom(seqPos, seqPos); + if (nodeNo != null) + { + return getNode(nodeNo[0]); + } + return null; } - public List getNodes() + /** + * Gets the match emission probability for a given symbol at a column in the + * alignment. + * + * @param alignColumn + * The index of the alignment column, starting at index 0. Index 0 + * usually corresponds to index 1 in the HMM. + * @param symbol + * The symbol for which the desired probability is being requested. + * @return + * + */ + public double getMatchEmissionProbability(int alignColumn, char symbol) { - return nodes; + HMMNode node = getNodeForColumn(alignColumn); + int symbolIndex = getSymbolIndex(symbol); + if (node != null && symbolIndex != -1) + { + return node.getMatchEmission(symbolIndex); + } + return 0D; } - public void setNodes(List nodes) + /** + * Gets the insert emission probability for a given symbol at a column in the + * alignment. + * + * @param alignColumn + * The index of the alignment column, starting at index 0. Index 0 + * usually corresponds to index 1 in the HMM. + * @param symbol + * The symbol for which the desired probability is being requested. + * @return + * + */ + public double getInsertEmissionProbability(int alignColumn, char symbol) { - this.nodes = nodes; + HMMNode node = getNodeForColumn(alignColumn); + int symbolIndex = getSymbolIndex(symbol); + if (node != null && symbolIndex != -1) + { + return node.getInsertEmission(symbolIndex); + } + return 0D; } /** - * gets the match emission at a node for a symbol - * @param nodeIndex - * position of node in model - * @param symbolIndex - * index of symbol being searched + * Gets the state transition probability for a given symbol at a column in the + * alignment. + * + * @param alignColumn + * The index of the alignment column, starting at index 0. Index 0 + * usually corresponds to index 1 in the HMM. + * @param symbol + * The symbol for which the desired probability is being requested. * @return - * negative log probability of a match emission of the given symbol + * */ - public double getMatchEmission(int nodeIndex, int symbolIndex) + public double getStateTransitionProbability(int alignColumn, + int transition) { - double value = nodes.get(nodeIndex).getMatchEmissions().get(symbolIndex); - return value; + HMMNode node = getNodeForColumn(alignColumn); + if (node != null) + { + return node.getStateTransition(transition); + } + return 0D; } /** - * gets the insert emission at a node for a symbol + * Returns the sequence position linked to the node at the given index. This + * corresponds to an aligned column position (counting from 1). + * * @param nodeIndex - * position of node in model - * @param symbolIndex - * index of symbol being searched + * The index of the node, starting from index 1. Index 0 is the begin + * node, which does not correspond to a column in the alignment. * @return - * negative log probability of an insert emission of the given symbol */ - public double getInsertEmission(int nodeIndex, int symbolIndex) + public int getNodeMapPosition(int nodeIndex) { - double value = nodes.get(nodeIndex).getInsertEmissions().get(symbolIndex); - return value; + return nodes.get(nodeIndex).getResidueNumber(); } /** - * gets the state transition at a node for a specific transition + * Returns the consensus residue at the specified node. + * * @param nodeIndex - * position of node in model - * @param transitionIndex - * index of stransition being searched + * The index of the specified node. * @return - * negative log probability of a state transition of the given type */ - public double getStateTransition(int nodeIndex, int transitionIndex) - { - double value = nodes.get(nodeIndex).getStateTransitions() - .get(transitionIndex); - return value; - } - - public Integer getNodeAlignmentColumn(int nodeIndex) - { - Integer value = nodes.get(nodeIndex).getAlignmentColumn(); - return value; - } - public char getConsensusResidue(int nodeIndex) { char value = nodes.get(nodeIndex).getConsensusResidue(); return value; } + /** + * Returns the reference annotation at the specified node. + * + * @param nodeIndex + * The index of the specified node. + * @return + */ public char getReferenceAnnotation(int nodeIndex) { char value = nodes.get(nodeIndex).getReferenceAnnotation(); return value; } + /** + * Returns the mask value at the specified node. + * + * @param nodeIndex + * The index of the specified node. + * @return + */ public char getMaskedValue(int nodeIndex) { char value = nodes.get(nodeIndex).getMaskValue(); return value; } + /** + * Returns the consensus structure at the specified node. + * + * @param nodeIndex + * The index of the specified node. + * @return + */ public char getConsensusStructure(int nodeIndex) { char value = nodes.get(nodeIndex).getConsensusStructure(); @@ -334,287 +456,217 @@ public class HiddenMarkovModel } /** - * returns the average match emission for a given symbol - * @param symbolIndex - * index of symbol - * @return - * average negative log propbability of a match emission of the given symbol + * Sets a property read from an HMM file + * + * @param key + * @param value */ - public double getAverageMatchEmission(int symbolIndex) - { - double value = nodes.get(0).getMatchEmissions().get(symbolIndex); - return value; - } - - public int getNumberOfSymbols() + public void setProperty(String key, String value) { - return numberOfSymbols; + fileProperties.put(key, value); } - public void setNumberOfSymbols(int numberOfSymbols) + /** + * Temporary implementation, should not be used. + * + * @return + */ + public String getViterbi() { - this.numberOfSymbols = numberOfSymbols; + String value; + value = fileProperties.get(HMMFile.VITERBI); + return value; } - public List getSymbols() + /** + * Temporary implementation, should not be used. + * + * @return + */ + public String getMSV() { - return symbols; + String value; + value = fileProperties.get(HMMFile.MSV); + return value; } - /** - * fills symbol array and also finds numberOfSymbols + * Temporary implementation, should not be used. * - * @param parser - * scanner scanning symbol line in file + * @return */ - public void fillSymbols(Scanner parser) + public String getForward() { - while (parser.hasNext()) - { - String strSymbol = parser.next(); - char[] symbol = strSymbol.toCharArray(); - symbols.add(symbol[0]); - } - numberOfSymbols = symbols.size(); + String value; + value = fileProperties.get(HMMFile.FORWARD); + return value; } /** - * adds file property + * Constructs the consensus sequence based on the most probable symbol at each + * position. Gap characters are inserted for discontinuities in the node map + * numbering (if provided), else an ungapped sequence is generated. + *

+ * A mapping between the HMM nodes and residue positions of the sequence is + * also built and saved. * - * @param key - * @param value + * @return */ - public void addFileProperty(String key, String value) + void buildConsensusSequence() { - fileProperties.put(key, value); - } + List toResidues = new ArrayList<>(); - public boolean referenceAnnotationIsActive() - { - String status; - status = fileProperties.get(REFERENCE_ANNOTATION); - if (status == null) - { - return false; - } - switch (status) - { - case YES: - return true; - case NO: - return false; - default: - return false; - } + /* + * if the HMM provided a map to sequence, use those start/end values, + * else just treat it as for a contiguous sequence numbered from 1 + */ + boolean hasMap = getBooleanProperty(HMMFile.MAP); + int start = hasMap ? getNode(1).getResidueNumber() : 1; + int endResNo = hasMap ? getNode(nodes.size() - 1).getResidueNumber() + : (start + getLength() - 1); + char[] sequence = new char[endResNo]; - } + int lastResNo = start - 1; + int seqOffset = -1; + int gapCount = 0; - public boolean maskValueIsActive() - { - String status; - status = fileProperties.get(MASKED_VALUE); - if (status == null) + + for (int seqN = 0; seqN < start; seqN++) { - return false; + sequence[seqN] = GAP_DASH; + seqOffset++; } - switch (status) + + for (int nodeNo = 1; nodeNo < nodes.size(); nodeNo++) { - case YES: - return true; - case NO: - return false; - default: - return false; + HMMNode node = nodes.get(nodeNo); + final int resNo = hasMap ? node.getResidueNumber() : lastResNo + 1; + + /* + * insert gaps if map numbering is not continuous + */ + while (resNo > lastResNo + 1) + { + sequence[seqOffset++] = GAP_DASH; + lastResNo++; + gapCount++; + } + char consensusResidue = node.getConsensusResidue(); + if (GAP_DASH == consensusResidue) + { + /* + * no residue annotation in HMM - scan for the symbol + * with the highest match emission probability + */ + int symbolIndex = node.getMaxMatchEmissionIndex(); + consensusResidue = alphabet.charAt(symbolIndex); + if (node.getMatchEmission(symbolIndex) < 0.5D) + { + // follow convention of lower case if match emission prob < 0.5 + consensusResidue = Character.toLowerCase(consensusResidue); + } + } + sequence[seqOffset++] = consensusResidue; + lastResNo = resNo; } + Sequence seq = new Sequence(getName(), sequence, start, + lastResNo - gapCount); + seq.createDatasetSequence(); + seq.setHMM(this); + this.hmmSeq = seq; + + /* + * construct and store Mapping of nodes to residues + * note as constructed this is just an identity mapping, + * but it allows for greater flexibility in future + */ + List fromNodes = new ArrayList<>(); + fromNodes.add(new int[] { 1, getLength() }); + toResidues.add(new int[] { seq.getStart(), seq.getEnd() }); + MapList mapList = new MapList(fromNodes, toResidues, 1, 1); + mapToHmmConsensus = new Mapping(seq.getDatasetSequence(), mapList); } - public boolean consensusResidueIsActive() - { - String status; - status = fileProperties.get(CONSENSUS_RESIDUE); - if (status == null) - { - return false; - } - switch (status) - { - case YES: - return true; - case NO: - return false; - default: - return false; - } + /** + * Answers the aligned consensus sequence for the profile. Note this will + * return null if called before setNodes has been called. + * + * @return + */ + public SequenceI getConsensusSequence() + { + return hmmSeq; } - public boolean consensusStructureIsActive() + /** + * Answers the index position (0...) of the given symbol, or -1 if not a valid + * symbol for this HMM + * + * @param symbol + * @return + */ + private int getSymbolIndex(char symbol) { - String status; - status = fileProperties.get(CONSENSUS_STRUCTURE); - if (status == null) - { - return false; - } - switch (status) + /* + * symbolIndexLookup holds the index for 'A' to 'Z' + */ + char c = Character.toUpperCase(symbol); + if ('A' <= c && c <= 'Z') { - case YES: - return true; - case NO: - return false; - default: - return false; + return symbolIndexLookup[c - 'A']; } - + return -1; } - public boolean mapIsActive() + /** + * Sets the nodes of this HMM, and also extracts the HMM consensus sequence + * and a mapping between node numbers and sequence positions + * + * @param nodeList + */ + public void setNodes(List nodeList) { - String status; - status = fileProperties.get(MAP); - if (status == null) - { - return false; - } - switch (status) + nodes = nodeList; + if (nodes.size() > 1) { - case YES: - return true; - case NO: - return false; - default: - return false; + buildConsensusSequence(); } - - } - - public void setAlignmentColumn(int nodeIndex, int column) - { - nodes.get(nodeIndex).setAlignmentColumn(column); - } - - public void setReferenceAnnotation(int nodeIndex, char value) - { - nodes.get(nodeIndex).setReferenceAnnotation(value); - } - - public void setConsensusResidue(int nodeIndex, char value) - { - nodes.get(nodeIndex).setConsensusResidue(value); - } - - public void setConsensusStructure(int nodeIndex, char value) - { - nodes.get(nodeIndex).setConsensusStructure(value); - } - - public void setMaskValue(int nodeIndex, char value) - { - nodes.get(nodeIndex).setMaskValue(value); - } - - public String getGatheringThreshold() - { - String value; - value = fileProperties.get("GA"); - return value; - } - - public String getNoiseCutoff() - { - String value; - value = fileProperties.get("NC"); - return value; - } - - public String getTrustedCutoff() - { - String value; - value = fileProperties.get("TC"); - return value; } - public String getViterbi() + /** + * Sets the aligned consensus sequence this HMM is the model for + * + * @param hmmSeq + */ + public void setHmmSeq(SequenceI hmmSeq) { - String value; - value = fileProperties.get(VITERBI); - return value; + this.hmmSeq = hmmSeq; } - public String getMSV() + public void setBackgroundFrequencies(Map bkgdFreqs) { - String value; - value = fileProperties.get(MSV); - return value; + backgroundFrequencies = bkgdFreqs; } - public String getForward() + public void setBackgroundFrequencies(ResidueCount bkgdFreqs) { - String value; - value = fileProperties.get(FORWARD); - return value; - } + backgroundFrequencies = new HashMap<>(); - public void setMAPStatus(boolean status) - { - if (status == true) - { - fileProperties.put(MAP, YES); - } - else - { - fileProperties.put(MAP, NO); - } - } + int total = bkgdFreqs.getTotalResidueCount(); - public void setReferenceAnnotationStatus(boolean status) - { - if (status == true) - { - fileProperties.put(REFERENCE_ANNOTATION, YES); - } - else + for (char c : bkgdFreqs.getSymbolCounts().symbols) { - fileProperties.put(REFERENCE_ANNOTATION, NO); + backgroundFrequencies.put(c, bkgdFreqs.getCount(c) * 1f / total); } - } - public void setMaskedValueStatus(boolean status) - { - if (status == true) - { - fileProperties.put(MASKED_VALUE, YES); - } - else - { - fileProperties.put(MASKED_VALUE, NO); - } } - public void setConsensusResidueStatus(boolean status) + public Map getBackgroundFrequencies() { - if (status == true) - { - fileProperties.put(CONSENSUS_RESIDUE, YES); - } - else - { - fileProperties.put(CONSENSUS_RESIDUE, NO); - } + return backgroundFrequencies; } - public void setConsensusStructureStatus(boolean status) - { - if (status == true) - { - fileProperties.put(CONSENSUS_STRUCTURE, YES); - } - else - { - fileProperties.put(CONSENSUS_STRUCTURE, NO); - } - } }