X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fjalview%2Fio%2FHMMFile.java;h=07f29c8817597c97f1ba4b74908ee1956ceb9550;hb=b5667f39acdf309cd92881b73edfda591e0acaf4;hp=dc5c699fff9d0675365035147f22df68e4191dfa;hpb=2e6deb5d089d95ce34b15828766479b4f7803f5c;p=jalview.git diff --git a/src/jalview/io/HMMFile.java b/src/jalview/io/HMMFile.java index dc5c699..07f29c8 100644 --- a/src/jalview/io/HMMFile.java +++ b/src/jalview/io/HMMFile.java @@ -1,21 +1,20 @@ package jalview.io; +import jalview.api.AlignExportSettingI; +import jalview.api.AlignmentViewPanel; import jalview.datamodel.HMMNode; import jalview.datamodel.HiddenMarkovModel; import jalview.datamodel.SequenceI; import java.io.BufferedReader; -import java.io.FileNotFoundException; import java.io.IOException; -import java.io.PrintWriter; -import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; import java.util.Scanner; /** - * Adds capability to read in and write out HMMER3 files. Currently only supports HMMER3/f. + * Adds capability to read in and write out HMMER3 files. . * * * @author TZVanaalten @@ -24,72 +23,141 @@ import java.util.Scanner; public class HMMFile extends AlignFile implements AlignmentFileReaderI, AlignmentFileWriterI { - // HMM to store file data - private HiddenMarkovModel hmm = new HiddenMarkovModel(); + private static final String TERMINATOR = "//"; + /* + * keys to data in HMM file, used to store as properties of the HiddenMarkovModel + */ + public static final String HMM = "HMM"; + + public static final String NAME = "NAME"; + + public static final String ACCESSION_NUMBER = "ACC"; + + public static final String DESCRIPTION = "DESC"; + + public static final String LENGTH = "LENG"; + + public static final String MAX_LENGTH = "MAXL"; + + public static final String ALPHABET = "ALPH"; + + public static final String DATE = "DATE"; + + public static final String COMMAND_LOG = "COM"; + + public static final String NUMBER_OF_SEQUENCES = "NSEQ"; + + public static final String EFF_NUMBER_OF_SEQUENCES = "EFFN"; + + public static final String CHECK_SUM = "CKSUM"; + + public static final String STATISTICS = "STATS"; + public static final String COMPO = "COMPO"; + public static final String GATHERING_THRESHOLD = "GA"; - // number of possible transitions - private final int NUMBER_OF_TRANSITIONS = 7; + public static final String TRUSTED_CUTOFF = "TC"; - private final String NEW_LINE = "\n"; + public static final String NOISE_CUTOFF = "NC"; - // file header - String fileHeader; + public static final String VITERBI = "VITERBI"; - //number of symbols in the alphabet used in the hidden Markov model - int numberOfSymbols; + public static final String MSV = "MSV"; - private final String SPACE = " "; + public static final String FORWARD = "FORWARD"; - private final String COMPO = "COMPO"; + public static final String MAP = "MAP"; - private final String EMPTY = ""; + public static final String REFERENCE_ANNOTATION = "RF"; - //This is a line that needs to be added to each HMMER£ file. It is purely for readability. - private static final String TRANSITIONTYPELINE = "m->m m->i m->d i->m i->i d->m d->d"; + public static final String CONSENSUS_RESIDUE = "CONS"; + + public static final String CONSENSUS_STRUCTURE = "CS"; + + public static final String MASKED_VALUE = "MM"; + + private static final String ALPH_AMINO = "amino"; + + private static final String ALPH_DNA = "DNA"; + + private static final String ALPH_RNA = "RNA"; + + private static final String ALPHABET_AMINO = "ACDEFGHIKLMNPQRSTVWY"; + + private static final String ALPHABET_DNA = "ACGT"; + + private static final String ALPHABET_RNA = "ACGU"; + + private static final int NUMBER_OF_TRANSITIONS = 7; + + private static final String SPACE = " "; + + /* + * optional guide line added to an output HMMER file, purely for readability + */ + private static final String TRANSITIONTYPELINE = " m->m m->i m->d i->m i->i d->m d->d"; + + private static String NL = System.lineSeparator(); + + private HiddenMarkovModel hmm; + + // number of symbols in the alphabet used in the hidden Markov model + private int numberOfSymbols; + + /** + * Constructor that parses immediately + * + * @param inFile + * @param type + * @throws IOException + */ + public HMMFile(String inFile, DataSourceType type) throws IOException + { + super(inFile, type); + } /** - * Constructor for HMMFile + * Constructor that parses immediately + * * @param source * @throws IOException */ public HMMFile(FileParse source) throws IOException { - super(false, source); + super(source); } /** - * Default constructor, do not use! + * Default constructor */ public HMMFile() { - } /** - * Returns the HMM produced by reading in a HMMER3 file. + * Constructor for HMMFile used for exporting * - * @return + * @param hmm */ - public HiddenMarkovModel getHMM() + public HMMFile(HiddenMarkovModel markov) { - return hmm; + hmm = markov; } /** - * Sets the HMM used in this file. + * Returns the HMM produced by parsing a HMMER3 file * - * @param model + * @return */ - public void setHMM(HiddenMarkovModel model) + public HiddenMarkovModel getHMM() { - this.hmm = model; + return hmm; } /** - * Gets the name of the hidden Markov model. + * Gets the name of the hidden Markov model * * @return */ @@ -99,220 +167,253 @@ public class HMMFile extends AlignFile } /** - * Reads the data from HMM file into the HMM field on this object. - * - * @throws IOException + * Reads the data from HMM file into the HMM model */ @Override - public void parse() throws IOException + public void parse() { - parseFileProperties(dataIn); - parseModel(dataIn); + try + { + hmm = new HiddenMarkovModel(); + parseHeaderLines(dataIn); + parseModel(dataIn); + } catch (Exception e) + { + e.printStackTrace(); + } } - - /** - * Imports the file properties from a HMMER3 file. + * Reads the header properties from a HMMER3 file and saves them in the + * HiddeMarkovModel. This method exits after reading the next line after the + * HMM line. * * @param input - * The buffered reader used to read in the file. * @throws IOException */ - void parseFileProperties(BufferedReader input) throws IOException + void parseHeaderLines(BufferedReader input) throws IOException { - boolean readingFile = true; - fileHeader = input.readLine(); + boolean readingHeaders = true; + hmm.setFileHeader(input.readLine()); String line = input.readLine(); - while (readingFile) + while (readingHeaders && line != null) { - if (line != null) + Scanner parser = new Scanner(line); + String next = parser.next(); + if (ALPHABET.equals(next)) { - Scanner parser = new Scanner(line); - String next = parser.next(); - if ("HMM".equals(next)) // indicates start of HMM data (end of file - // properties) - { - readingFile = false; - hmm.fillSymbols(parser); - numberOfSymbols = hmm.getNumberOfSymbols(); - } - else if ("STATS".equals(next)) - { - parser.next(); - String key; - String value; - key = parser.next(); - value = parser.next() + SPACE + SPACE + parser.next(); - hmm.addFileProperty(key, value); - } - else + String alphabetType = parser.next(); + hmm.setProperty(ALPHABET, alphabetType); + String alphabet = ALPH_DNA.equalsIgnoreCase(alphabetType) + ? ALPHABET_DNA + : (ALPH_RNA.equalsIgnoreCase(alphabetType) ? ALPHABET_RNA + : ALPHABET_AMINO); + numberOfSymbols = hmm.setAlphabet(alphabet); + } + else if (HMM.equals(next)) + { + readingHeaders = false; + String symbols = line.substring(line.indexOf(HMM) + HMM.length()); + numberOfSymbols = hmm.setAlphabet(symbols); + } + else if (STATISTICS.equals(next)) + { + parser.next(); + String key; + String value; + key = parser.next(); + value = parser.next() + SPACE + SPACE + parser.next(); + hmm.setProperty(key, value); + } + else + { + String key = next; + String value = parser.next(); + while (parser.hasNext()) { - String key = next; - String value = parser.next(); - while (parser.hasNext()) - { - value = value + SPACE + parser.next(); - } - hmm.addFileProperty(key, value); + value = value + SPACE + parser.next(); } - parser.close(); + hmm.setProperty(key, value); } + parser.close(); line = input.readLine(); - if (line == null) - { - readingFile = false; - } } - } /** - * Parses the model data from the HMMER3 file + * Parses the model data from the HMMER3 file. The input buffer should be + * positioned at the (optional) COMPO line if there is one, else at the insert + * emissions line for the BEGIN node of the model. * * @param input - * The buffered reader used to read the file. * @throws IOException */ void parseModel(BufferedReader input) throws IOException { - for (int i = 0; i < hmm.getLength() + 1; i++) + /* + * specification says there must always be an HMM header (already read) + * and one more header (guide headings) which is skipped here + */ + int nodeNo = 0; + String line = input.readLine(); + List nodes = new ArrayList<>(); + + while (line != null && !TERMINATOR.equals(line)) { - hmm.getNodes().add(new HMMNode()); - String next; - String line; - line = input.readLine(); - Scanner matchReader = new Scanner(line); - next = matchReader.next(); - if (next.equals(COMPO) || i > 0) + HMMNode node = new HMMNode(); + nodes.add(node); + Scanner scanner = new Scanner(line); + String next = scanner.next(); + + /* + * expect COMPO (optional) for average match emissions + * or a node number followed by node's match emissions + */ + if (COMPO.equals(next) || nodeNo > 0) { - // stores match emission line in list - List matches = new ArrayList<>(); - matches = fillList(matchReader, numberOfSymbols); - hmm.getNodes().get(i).setMatchEmissions(matches); - if (i > 0) + /* + * parse match emissions + */ + double[] matches = parseDoubles(scanner, numberOfSymbols); + node.setMatchEmissions(matches); + if (!COMPO.equals(next)) { - parseAnnotations(matchReader, i); + int resNo = parseAnnotations(scanner, node); + if (resNo == 0) + { + /* + * no MAP annotation provided, just number off from 0 (begin node) + */ + resNo = nodeNo; + } + node.setResidueNumber(resNo); } + line = input.readLine(); } - matchReader.close(); - // stores insert emission line in list + scanner.close(); + + /* + * parse insert emissions + */ + scanner = new Scanner(line); + double[] inserts = parseDoubles(scanner, numberOfSymbols); + node.setInsertEmissions(inserts); + scanner.close(); + + /* + * parse state transitions + */ line = input.readLine(); - Scanner insertReader = new Scanner(line); - List inserts = new ArrayList<>(); - inserts = fillList(insertReader, numberOfSymbols); - hmm.getNodes().get(i).setInsertEmissions(inserts); - insertReader.close(); - - // stores state transition line in list + scanner = new Scanner(line); + double[] transitions = parseDoubles(scanner, + NUMBER_OF_TRANSITIONS); + node.setStateTransitions(transitions); + scanner.close(); line = input.readLine(); - Scanner transitionReader = new Scanner(line); - List transitions = new ArrayList<>(); - transitions = fillList(transitionReader, NUMBER_OF_TRANSITIONS); - hmm.getNodes().get(i).setStateTransitions(transitions); - transitionReader.close(); + + nodeNo++; } + hmm.setNodes(nodes); } /** - * Parses the annotations on the match emission line. + * Parses the annotations on the match emission line and add them to the node. + * (See p109 of the HMMER User Guide (V3.1b2) for the specification.) Returns + * the residue position that the node maps to, if provided, else zero. * * @param scanner - * The scanner which is processing match emission line. - * @param index - * The index of node which is being scanned. + * @param node */ - void parseAnnotations(Scanner scanner, int index) + int parseAnnotations(Scanner scanner, HMMNode node) { - if (hmm.mapIsActive()) + int mapTo = 0; + + /* + * map from hmm node to sequence position, if provided + */ + if (scanner.hasNext()) { - int column; - column = scanner.nextInt(); - hmm.getNodes().get(index).setAlignmentColumn(column); - hmm.getNodeLookup().put(column, index); + String value = scanner.next(); + if (!"-".equals(value)) + { + try + { + mapTo = Integer.parseInt(value); + node.setResidueNumber(mapTo); + } catch (NumberFormatException e) + { + // ignore + } + } } - else + + /* + * hmm consensus residue if provided, else '-' + */ + if (scanner.hasNext()) { - scanner.next(); + node.setConsensusResidue(scanner.next().charAt(0)); } - char consensusR; - consensusR = charValue(scanner.next()); - hmm.getNodes().get(index).setConsensusResidue(consensusR); - - char reference; - reference = charValue(scanner.next()); - hmm.getNodes().get(index).setReferenceAnnotation(reference); + /* + * RF reference annotation, if provided, else '-' + */ + if (scanner.hasNext()) + { + node.setReferenceAnnotation(scanner.next().charAt(0)); + } + /* + * 'm' for masked position, if provided, else '-' + */ + if (scanner.hasNext()) + { + node.setMaskValue(scanner.next().charAt(0)); + } - char value; - value = charValue(scanner.next()); - hmm.getNodes().get(index).setMaskValue(value); + /* + * structure consensus symbol, if provided, else '-' + */ + if (scanner.hasNext()) + { + node.setConsensusStructure(scanner.next().charAt(0)); + } - char consensusS; - consensusS = charValue(scanner.next()); - hmm.getNodes().get(index).setConsensusStructure(consensusS); + return mapTo; } - /** - * Fills a list of doubles based on an input line. + * Fills an array of doubles parsed from an input line * * @param input - * The scanner for the line containing the data to be transferred to - * the list. * @param numberOfElements - * The number of elements in the list to be filled. - * @return filled list Returns the list of doubles. + * @return + * @throws IOException */ - static List fillList(Scanner input, - int numberOfElements) + static double[] parseDoubles(Scanner input, + int numberOfElements) throws IOException { - List list = new ArrayList<>(); + double[] values = new double[numberOfElements]; for (int i = 0; i < numberOfElements; i++) { - + if (!input.hasNext()) + { + throw new IOException("Incomplete data"); + } String next = input.next(); - if (next.contains("*")) // state transitions to or from delete states - // occasionally have values of -infinity. These - // values are represented by an * in the .hmm - // file. + if (next.contains("*")) { - list.add(Double.NEGATIVE_INFINITY); + values[i] = Double.NEGATIVE_INFINITY; } else { double prob = Double.valueOf(next); prob = Math.pow(Math.E, -prob); - list.add(prob); + values[i] = prob; } } - return list; - } - - - /** - * Writes a HMM to a file/ - * - * @param exportLocation - * Filename, URL or Pasted String to write to. - * @throws FileNotFoundException - * @throws UnsupportedEncodingException - * - **/ - - public void exportFile(String exportLocation) throws IOException - { - StringBuilder file = new StringBuilder(); - appendFileProperties(file); - appendModel(file); - file.append("//"); - - PrintWriter output = new PrintWriter(exportLocation); - output.append(file); - output.close(); - + return values; } /** @@ -325,25 +426,19 @@ public class HMMFile extends AlignFile * @param columnSeparation * The separation between subsequent data entries. * @param data - * The list fo data to be added to the String. + * The list of data to be added to the String. * @return */ String addData(int initialColumnSeparation, int columnSeparation, List data) { - String line = EMPTY; - int index = 0; + String line = ""; + boolean first = true; for (String value : data) { - if (index == 0) - { - line += String.format("%" + initialColumnSeparation + "s", value); - } - else - { - line += String.format("%" + columnSeparation + "s", value); - } - index++; + int sep = first ? initialColumnSeparation : columnSeparation; + line += String.format("%" + sep + "s", value); + first = false; } return line; } @@ -366,23 +461,22 @@ public class HMMFile extends AlignFile } /** - * Converts a list of doubles into a list of Strings, rounded to the nearest - * 5th decimal place. + * Converts an array of doubles into a list of Strings, rounded to the nearest + * 5th decimal place * - * @param list + * @param doubles * @param noOfDecimals * @return */ - List doubleListToStringList(List list) + List doublesToStringList(double[] doubles) { List strList = new ArrayList<>(); - for (double value : list) + for (double value : doubles) { String strValue; if (value > 0) { strValue = String.format("%.5f", value); - } else if (value == -0.00000d) { @@ -392,265 +486,231 @@ public class HMMFile extends AlignFile { strValue = "*"; } - strList.add(strValue); } return strList; } /** - * Converts a primitive array of Strings to a list of Strings. + * Appends model data in string format to the string builder * - * @param array - * @return + * @param output */ - List stringArrayToStringList(String[] array) + void appendModelAsString(StringBuilder output) { - List list = new ArrayList<>(); - for (String value : array) + output.append(HMM).append(" "); + String charSymbols = hmm.getSymbols(); + for (char c : charSymbols.toCharArray()) { - list.add(value); + output.append(String.format("%9s", c)); } - - return list; - } - - /** - * Appends the hidden Markov model data to the StringBuilder containing the - * output - * - * @param file - * The StringBuilder containing the output. - */ - void appendModel(StringBuilder file) - { - String symbolLine = "HMM"; - List charSymbols = hmm.getSymbols(); - List strSymbols; - strSymbols = charListToStringList(charSymbols); - symbolLine += addData(11, 9, strSymbols); - file.append(symbolLine + NEW_LINE); - file.append(TRANSITIONTYPELINE + NEW_LINE); + output.append(NL).append(TRANSITIONTYPELINE); int length = hmm.getLength(); - for (int node = 0; node <= length; node++) + for (int nodeNo = 0; nodeNo <= length; nodeNo++) { - String matchLine; - if (node == 0) - { - matchLine = String.format("%7s", "COMPO"); - } - else - { - matchLine = String.format("%7s", node); - } + String matchLine = String.format("%7s", + nodeNo == 0 ? COMPO : Integer.toString(nodeNo)); - List strMatches; - List doubleMatches; - doubleMatches = hmm.getNode(node).getMatchEmissions(); - convertListToLogSpace(doubleMatches); - strMatches = doubleListToStringList(doubleMatches); + double[] doubleMatches = convertToLogSpace( + hmm.getNode(nodeNo).getMatchEmissions()); + List strMatches = doublesToStringList(doubleMatches); matchLine += addData(10, 9, strMatches); - - if (node != 0) + if (nodeNo != 0) { - matchLine += SPACE + hmm.getNodeAlignmentColumn(node); - matchLine += SPACE + hmm.getConsensusResidue(node); - matchLine += SPACE + hmm.getReferenceAnnotation(node); - matchLine += SPACE + hmm.getMaskedValue(node); - matchLine += SPACE + hmm.getConsensusStructure(node); - + matchLine += SPACE + (hmm.getNodeMapPosition(nodeNo)); + matchLine += SPACE + hmm.getConsensusResidue(nodeNo); + matchLine += SPACE + hmm.getReferenceAnnotation(nodeNo); + if (hmm.getFileHeader().contains("HMMER3/f")) + { + matchLine += SPACE + hmm.getMaskedValue(nodeNo); + matchLine += SPACE + hmm.getConsensusStructure(nodeNo); + } } - file.append(matchLine + NEW_LINE); + output.append(NL).append(matchLine); - String insertLine = EMPTY; - List strInserts; - List doubleInserts; - doubleInserts = hmm.getNode(node).getInsertEmissions(); - convertListToLogSpace(doubleInserts); - strInserts = doubleListToStringList(doubleInserts); + String insertLine = ""; + + double[] doubleInserts = convertToLogSpace( + hmm.getNode(nodeNo).getInsertEmissions()); + List strInserts = doublesToStringList(doubleInserts); insertLine += addData(17, 9, strInserts); - file.append(insertLine + NEW_LINE); + output.append(NL).append(insertLine); - String transitionLine = EMPTY; - List strTransitions; - List doubleTransitions; - doubleTransitions = hmm.getNode(node).getStateTransitions(); - convertListToLogSpace(doubleTransitions); - strTransitions = doubleListToStringList(doubleTransitions); + String transitionLine = ""; + double[] doubleTransitions = convertToLogSpace( + hmm.getNode(nodeNo).getStateTransitions()); + List strTransitions = doublesToStringList( + doubleTransitions); transitionLine += addData(17, 9, strTransitions); - file.append(transitionLine + NEW_LINE); + output.append(NL).append(transitionLine); } } /** - * Appends the hidden Markov model file properties to the StringBuilder - * containing the output + * Appends formatted HMM file properties to the string builder * - * @param file - * The StringBuilder containing the output. + * @param output */ - void appendFileProperties(StringBuilder file) + void appendProperties(StringBuilder output) { - String line; - - file.append(fileHeader + NEW_LINE); - - line = String.format("%-5s %1s", "NAME", hmm.getName()); - file.append((line + NEW_LINE)); + output.append(hmm.getFileHeader()); + + String format = "%n%-5s %1s"; + appendProperty(output, format, NAME); + appendProperty(output, format, ACCESSION_NUMBER); + appendProperty(output, format, DESCRIPTION); + appendProperty(output, format, LENGTH); + appendProperty(output, format, MAX_LENGTH); + appendProperty(output, format, ALPHABET); + appendBooleanProperty(output, format, REFERENCE_ANNOTATION); + appendBooleanProperty(output, format, MASKED_VALUE); + appendBooleanProperty(output, format, CONSENSUS_RESIDUE); + appendBooleanProperty(output, format, CONSENSUS_STRUCTURE); + appendBooleanProperty(output, format, MAP); + appendProperty(output, format, DATE); + appendProperty(output, format, NUMBER_OF_SEQUENCES); + appendProperty(output, format, EFF_NUMBER_OF_SEQUENCES); + appendProperty(output, format, CHECK_SUM); + appendProperty(output, format, GATHERING_THRESHOLD); + appendProperty(output, format, TRUSTED_CUTOFF); + appendProperty(output, format, NOISE_CUTOFF); - if (hmm.getAccessionNumber() != null) + if (hmm.getMSV() != null) { - line = String.format("%-5s %1s", "ACC", hmm.getAccessionNumber()); - file.append((line + NEW_LINE)); - } + format = "%n%-19s %18s"; + output.append(String.format(format, "STATS LOCAL MSV", hmm.getMSV())); - if (hmm.getDescription() != null) - { - line = String.format("%-5s %1s", "DESC", hmm.getDescription()); - file.append((line + NEW_LINE)); - } - line = String.format("%-5s %1s", "LENG", hmm.getLength()); - file.append((line + NEW_LINE)); + output.append(String.format(format, "STATS LOCAL VITERBI", + hmm.getViterbi())); - if (hmm.getMaxInstanceLength() != null) - { - line = String.format("%-5s %1s", "MAXL", hmm.getMaxInstanceLength()); - file.append((line + NEW_LINE)); - } - line = String.format("%-5s %1s", "ALPH", hmm.getAlphabetType()); - file.append((line + NEW_LINE)); - - boolean status; - String statusStr; - - status = hmm.referenceAnnotationIsActive(); - statusStr = HiddenMarkovModel.findStringFromBoolean(status); - line = String.format("%-5s %1s", "RF", - statusStr); - file.append((line + NEW_LINE)); - - status = hmm.maskValueIsActive(); - statusStr = HiddenMarkovModel.findStringFromBoolean(status); - line = String.format("%-5s %1s", "MM", - statusStr); - file.append((line + NEW_LINE)); - - status = hmm.consensusResidueIsActive(); - statusStr = HiddenMarkovModel.findStringFromBoolean(status); - line = String.format("%-5s %1s", "CONS", - statusStr); - file.append((line + NEW_LINE)); - - status = hmm.consensusStructureIsActive(); - statusStr = HiddenMarkovModel.findStringFromBoolean(status); - line = String.format("%-5s %1s", "CS", - statusStr); - file.append((line + NEW_LINE)); - - status = hmm.mapIsActive(); - statusStr = HiddenMarkovModel.findStringFromBoolean(status); - line = String.format("%-5s %1s", "MAP", - statusStr); - file.append((line + NEW_LINE)); - - - if (hmm.getDate() != null) - { - line = String.format("%-5s %1s", "DATE", hmm.getDate()); - file.append((line + NEW_LINE)); - } - if (hmm.getNumberOfSequences() != null) - { - line = String.format("%-5s %1s", "NSEQ", hmm.getNumberOfSequences()); - file.append((line + NEW_LINE)); - } - if (hmm.getEffectiveNumberOfSequences() != null) - { - line = String.format("%-5s %1s", "EFFN", - hmm.getEffectiveNumberOfSequences()); - file.append((line + NEW_LINE)); - } - if (hmm.getCheckSum() != null) - { - line = String.format("%-5s %1s", "CKSUM", hmm.getCheckSum()); - file.append((line + NEW_LINE)); - } - if (hmm.getGatheringThreshold() != null) - { - line = String.format("%-5s %1s", "GA", hmm.getGatheringThreshold()); - file.append((line + NEW_LINE)); + output.append(String.format(format, "STATS LOCAL FORWARD", + hmm.getForward())); } + } - if (hmm.getTrustedCutoff() != null) - { - line = String.format("%-5s %1s", "TC", hmm.getTrustedCutoff()); - file.append((line + NEW_LINE)); - } - if (hmm.getNoiseCutoff() != null) + /** + * Appends 'yes' or 'no' for the given property, according to whether or not + * it is set in the HMM + * + * @param output + * @param format + * @param propertyName + */ + private void appendBooleanProperty(StringBuilder output, String format, + String propertyName) + { + boolean set = hmm.getBooleanProperty(propertyName); + output.append(String.format(format, propertyName, + set ? HiddenMarkovModel.YES : HiddenMarkovModel.NO)); + } + + /** + * Appends the value of the given property to the output, if not null + * + * @param output + * @param format + * @param propertyName + */ + private void appendProperty(StringBuilder output, String format, + String propertyName) + { + String value = hmm.getProperty(propertyName); + if (value != null) { - line = String.format("%-5s %1s", "NC", hmm.getNoiseCutoff()); - file.append((line + NEW_LINE)); + output.append(String.format(format, propertyName, value)); } - if (hmm.getMSV() != null) + } + + @Override + public String print(SequenceI[] sequences, boolean jvsuffix) + { + if (sequences[0].getHMM() != null) { - line = String.format("%-19s %18s", "STATS LOCAL MSV", hmm.getMSV()); - file.append((line + NEW_LINE)); - - line = String.format("%-19s %18s", "STATS LOCAL VITERBI", - hmm.getViterbi()); - file.append((line + NEW_LINE)); - - line = String.format("%-19s %18s", "STATS LOCAL FORWARD", - hmm.getForward()); - file.append((line + NEW_LINE)); + hmm = sequences[0].getHMM(); } + return print(); } - /** - * Returns the char value of a single lettered String. + * Prints the .hmm file to a String. * - * @param string * @return */ - char charValue(String string) + public String print() { - char character; - character = string.charAt(0); - return character; - + StringBuilder output = new StringBuilder(); + appendProperties(output); + output.append(NL); + appendModelAsString(output); + output.append(NL).append(TERMINATOR).append(NL); + return output.toString(); } - @Override - public String print(SequenceI[] seqs, boolean jvsuffix) + /** + * Converts the probabilities contained in an array into log space + * + * @param ds + */ + double[] convertToLogSpace(double[] ds) { + double[] converted = new double[ds.length]; + for (int i = 0; i < ds.length; i++) + { + double prob = ds[i]; + double logProb = -1 * Math.log(prob); - return null; + converted[i] = logProb; + } + return converted; } /** - * Converts the probabilities contained in a list into log space. - * - * @param list + * Returns the HMM sequence produced by reading a .hmm file. */ - void convertListToLogSpace(List list) + @Override + public SequenceI[] getSeqsAsArray() { + SequenceI hmmSeq = hmm.getConsensusSequence(); + SequenceI[] seq = new SequenceI[1]; + seq[0] = hmmSeq; + return seq; + } - for (int i = 0; i < list.size(); i++) - { - double prob = list.get(i); - double logProb = -1 * Math.log(prob); + @Override + public void setNewlineString(String newLine) + { + NL = newLine; + } - list.set(i, logProb); - } + @Override + public void setExportSettings(AlignExportSettingI exportSettings) + { + + } + + @Override + public void configureForView(AlignmentViewPanel viewpanel) + { + + } + @Override + public boolean hasWarningMessage() + { + return false; + } + @Override + public String getWarningMessage() + { + return "warning message"; } + }