X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fio%2FHMMFile.java;h=07f29c8817597c97f1ba4b74908ee1956ceb9550;hb=b5667f39acdf309cd92881b73edfda591e0acaf4;hp=e114f52033580657cbe7befaa0e080353f6d5c46;hpb=97d3ad401eb2bc5dba791f31616b87d88ea47e41;p=jalview.git diff --git a/src/jalview/io/HMMFile.java b/src/jalview/io/HMMFile.java index e114f52..07f29c8 100644 --- a/src/jalview/io/HMMFile.java +++ b/src/jalview/io/HMMFile.java @@ -1,5 +1,7 @@ package jalview.io; +import jalview.api.AlignExportSettingI; +import jalview.api.AlignmentViewPanel; import jalview.datamodel.HMMNode; import jalview.datamodel.HiddenMarkovModel; import jalview.datamodel.SequenceI; @@ -21,28 +23,91 @@ import java.util.Scanner; public class HMMFile extends AlignFile implements AlignmentFileReaderI, AlignmentFileWriterI { - // HMM to store file data - private HiddenMarkovModel hmm; + private static final String TERMINATOR = "//"; - // number of possible transitions - private static final int NUMBER_OF_TRANSITIONS = 7; + /* + * 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"; + + public static final String TRUSTED_CUTOFF = "TC"; + + public static final String NOISE_CUTOFF = "NC"; + + public static final String VITERBI = "VITERBI"; + + public static final String MSV = "MSV"; + + public static final String FORWARD = "FORWARD"; + + public static final String MAP = "MAP"; + + public static final String REFERENCE_ANNOTATION = "RF"; - private static final String NL = "\n"; + public static final String CONSENSUS_RESIDUE = "CONS"; - //number of symbols in the alphabet used in the hidden Markov model - int numberOfSymbols; + public static final String CONSENSUS_STRUCTURE = "CS"; - private final String SPACE = " "; + public static final String MASKED_VALUE = "MM"; - private final String COMPO = "COMPO"; + private static final String ALPH_AMINO = "amino"; - private final String EMPTY = ""; + private static final String ALPH_DNA = "DNA"; - //This is a line that needs to be added to each HMMER� file. It is purely for readability. + 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; + /** - * Parses immediately. + * Constructor that parses immediately * * @param inFile * @param type @@ -54,7 +119,7 @@ public class HMMFile extends AlignFile } /** - * Parses immediately. + * Constructor that parses immediately * * @param source * @throws IOException @@ -65,18 +130,16 @@ public class HMMFile extends AlignFile } /** - * Default constructor, do not use! + * Default constructor */ public HMMFile() { - } /** - * Constructor for HMMFile used for exporting. + * Constructor for HMMFile used for exporting * * @param hmm - * @param exportImmediately */ public HMMFile(HiddenMarkovModel markov) { @@ -84,17 +147,7 @@ public class HMMFile extends AlignFile } /** - * For testing, do not use. - * - * @param br - */ - HMMFile(BufferedReader br) - { - dataIn = br; - } - - /** - * Returns the HMM produced by reading in a HMMER3 file. + * Returns the HMM produced by parsing a HMMER3 file * * @return */ @@ -104,17 +157,7 @@ public class HMMFile extends AlignFile } /** - * Sets the HMM used in this file. - * - * @param model - */ - public void setHMM(HiddenMarkovModel model) - { - this.hmm = model; - } - - /** - * Gets the name of the hidden Markov model. + * Gets the name of the hidden Markov model * * @return */ @@ -124,228 +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 - { - hmm = new HiddenMarkovModel(); - parseFileProperties(dataIn); - parseModel(dataIn); - } - - /** - * Reads the data from HMM file into the HMM field on this object. - * - * @throws IOException - */ - - public void parse(BufferedReader br) throws IOException + public void parse() { - hmm = new HiddenMarkovModel(); - parseFileProperties(br); - parseModel(br); + 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; + 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; - 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 { + /* + * 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(); - int node = 0; - while (!"//".equals(line)) + List nodes = new ArrayList<>(); + + while (line != null && !TERMINATOR.equals(line)) { - hmm.getNodes().add(new HMMNode()); - String next; - Scanner matchReader = new Scanner(line); - next = matchReader.next(); - if (next.equals(COMPO) || node > 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(node).setMatchEmissions(matches); - if (node > 0) + /* + * parse match emissions + */ + double[] matches = parseDoubles(scanner, numberOfSymbols); + node.setMatchEmissions(matches); + if (!COMPO.equals(next)) { - parseAnnotations(matchReader, node); + 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 - line = input.readLine(); - Scanner insertReader = new Scanner(line); - List inserts = new ArrayList<>(); - inserts = fillList(insertReader, numberOfSymbols); - hmm.getNodes().get(node).setInsertEmissions(inserts); - insertReader.close(); - - // stores state transition 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 transitionReader = new Scanner(line); - List transitions = new ArrayList<>(); - transitions = fillList(transitionReader, NUMBER_OF_TRANSITIONS); - hmm.getNodes().get(node).setStateTransitions(transitions); - transitionReader.close(); + scanner = new Scanner(line); + double[] transitions = parseDoubles(scanner, + NUMBER_OF_TRANSITIONS); + node.setStateTransitions(transitions); + scanner.close(); line = input.readLine(); - node++; + + 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() && scanner.hasNext()) - { - int column; - column = scanner.nextInt(); - hmm.getNodes().get(index).setAlignmentColumn(column - 1); - hmm.getNodeLookup().put(column - 1, index); - } - else + int mapTo = 0; + + /* + * map from hmm node to sequence position, if provided + */ + if (scanner.hasNext()) { - scanner.next(); + String value = scanner.next(); + if (!"-".equals(value)) + { + try + { + mapTo = Integer.parseInt(value); + node.setResidueNumber(mapTo); + } catch (NumberFormatException e) + { + // ignore + } + } } + /* + * hmm consensus residue if provided, else '-' + */ if (scanner.hasNext()) { - char consensusR; - consensusR = charValue(scanner.next()); - hmm.getNodes().get(index).setConsensusResidue(consensusR); + node.setConsensusResidue(scanner.next().charAt(0)); } + /* + * RF reference annotation, if provided, else '-' + */ if (scanner.hasNext()) { - char reference; - reference = charValue(scanner.next()); - hmm.getNodes().get(index).setReferenceAnnotation(reference); + node.setReferenceAnnotation(scanner.next().charAt(0)); } + /* + * 'm' for masked position, if provided, else '-' + */ if (scanner.hasNext()) { - char value; - value = charValue(scanner.next()); - hmm.getNodes().get(index).setMaskValue(value); + node.setMaskValue(scanner.next().charAt(0)); } + + /* + * structure consensus symbol, if provided, else '-' + */ if (scanner.hasNext()) { - char consensusS; - consensusS = charValue(scanner.next()); - hmm.getNodes().get(index).setConsensusStructure(consensusS); + node.setConsensusStructure(scanner.next().charAt(0)); } - } - + 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, + 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; } } - if (list.size() < numberOfElements) - { - throw new IOException("Incomplete data"); - } - return list; + return values; } /** @@ -358,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; } @@ -399,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) { @@ -425,243 +486,154 @@ 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; - } - - /** - * Returns a string containing the model data. - */ - String getModelAsString() - { - StringBuffer output = new StringBuffer(); - String symbolLine = "HMM"; - List charSymbols = hmm.getSymbols(); - List strSymbols; - strSymbols = charListToStringList(charSymbols); - symbolLine += addData(11, 9, strSymbols); - output.append(symbolLine); - output.append(NL + TRANSITIONTYPELINE); + 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 = convertListToLogSpace( - hmm.getNode(node).getMatchEmissions()); - 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) + 1); - matchLine += SPACE + hmm.getConsensusResidue(node); - matchLine += SPACE + hmm.getReferenceAnnotation(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(node); - matchLine += SPACE + hmm.getConsensusStructure(node); + matchLine += SPACE + hmm.getMaskedValue(nodeNo); + matchLine += SPACE + hmm.getConsensusStructure(nodeNo); } - } - output.append(NL + matchLine); + output.append(NL).append(matchLine); - String insertLine = EMPTY; - List strInserts; - List doubleInserts; - doubleInserts = convertListToLogSpace( - hmm.getNode(node).getInsertEmissions()); - strInserts = doubleListToStringList(doubleInserts); + String insertLine = ""; + + double[] doubleInserts = convertToLogSpace( + hmm.getNode(nodeNo).getInsertEmissions()); + List strInserts = doublesToStringList(doubleInserts); insertLine += addData(17, 9, strInserts); - output.append(NL + insertLine); + output.append(NL).append(insertLine); - String transitionLine = EMPTY; - List strTransitions; - List doubleTransitions; - doubleTransitions = convertListToLogSpace( - hmm.getNode(node).getStateTransitions()); - strTransitions = doubleListToStringList(doubleTransitions); + String transitionLine = ""; + double[] doubleTransitions = convertToLogSpace( + hmm.getNode(nodeNo).getStateTransitions()); + List strTransitions = doublesToStringList( + doubleTransitions); transitionLine += addData(17, 9, strTransitions); - output.append(NL + transitionLine); + output.append(NL).append(transitionLine); } - return output.toString(); } /** - * Returns a String containing the HMM file properties + * Appends formatted HMM file properties to the string builder + * + * @param output */ - String getFilePropertiesAsString() + void appendProperties(StringBuilder output) { - StringBuffer output = new StringBuffer(); - String line; - output.append(hmm.getFileHeader()); - - line = String.format("%-5s %1s", "NAME", hmm.getName()); - output.append(NL + line); - if (hmm.getAccessionNumber() != null) - { - line = String.format("%-5s %1s", "ACC", hmm.getAccessionNumber()); - output.append(NL + line); - } + 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.getDescription() != null) + if (hmm.getMSV() != null) { - line = String.format("%-5s %1s", "DESC", hmm.getDescription()); - output.append(NL + line); - } - line = String.format("%-5s %1s", "LENG", hmm.getLength()); - output.append(NL + line); + format = "%n%-19s %18s"; + output.append(String.format(format, "STATS LOCAL MSV", hmm.getMSV())); - if (hmm.getMaxInstanceLength() != null) - { - line = String.format("%-5s %1s", "MAXL", hmm.getMaxInstanceLength()); - output.append(NL + line); - } - line = String.format("%-5s %1s", "ALPH", hmm.getAlphabetType()); - output.append(NL + line); - - boolean status; - String statusStr; - - status = hmm.referenceAnnotationIsActive(); - statusStr = HiddenMarkovModel.findStringFromBoolean(status); - line = String.format("%-5s %1s", "RF", - statusStr); - output.append(NL + line); - - status = hmm.maskValueIsActive(); - statusStr = HiddenMarkovModel.findStringFromBoolean(status); - line = String.format("%-5s %1s", "MM", - statusStr); - output.append(NL + line); - - status = hmm.consensusResidueIsActive(); - statusStr = HiddenMarkovModel.findStringFromBoolean(status); - line = String.format("%-5s %1s", "CONS", - statusStr); - output.append(NL + line); - - status = hmm.consensusStructureIsActive(); - statusStr = HiddenMarkovModel.findStringFromBoolean(status); - line = String.format("%-5s %1s", "CS", - statusStr); - output.append(NL + line); - - status = hmm.mapIsActive(); - statusStr = HiddenMarkovModel.findStringFromBoolean(status); - line = String.format("%-5s %1s", "MAP", - statusStr); - output.append(NL + line); - - - if (hmm.getDate() != null) - { - line = String.format("%-5s %1s", "DATE", hmm.getDate()); - output.append(NL + line); - } - if (hmm.getNumberOfSequences() != null) - { - line = String.format("%-5s %1s", "NSEQ", hmm.getNumberOfSequences()); - output.append(NL + line); - } - if (hmm.getEffectiveNumberOfSequences() != null) - { - line = String.format("%-5s %1s", "EFFN", - hmm.getEffectiveNumberOfSequences()); - output.append(NL + line); - } - if (hmm.getCheckSum() != null) - { - line = String.format("%-5s %1s", "CKSUM", hmm.getCheckSum()); - output.append(NL + line); - } - if (hmm.getGatheringThreshold() != null) - { - line = String.format("%-5s %1s", "GA", hmm.getGatheringThreshold()); - output.append(NL + line); - } + output.append(String.format(format, "STATS LOCAL VITERBI", + hmm.getViterbi())); - if (hmm.getTrustedCutoff() != null) - { - line = String.format("%-5s %1s", "TC", hmm.getTrustedCutoff()); - output.append(NL + line); - } - if (hmm.getNoiseCutoff() != null) - { - line = String.format("%-5s %1s", "NC", hmm.getNoiseCutoff()); - output.append(NL + line); + output.append(String.format(format, "STATS LOCAL FORWARD", + hmm.getForward())); } - if (hmm.getMSV() != null) - { - line = String.format("%-19s %18s", "STATS LOCAL MSV", hmm.getMSV()); - output.append(NL + line); - - line = String.format("%-19s %18s", "STATS LOCAL VITERBI", - hmm.getViterbi()); - output.append(NL + line); - - line = String.format("%-19s %18s", "STATS LOCAL FORWARD", - hmm.getForward()); - output.append(NL + line); - } - return output.toString(); } - /** - * Returns the char value of a single lettered String. + * Appends 'yes' or 'no' for the given property, according to whether or not + * it is set in the HMM * - * @param string - * @return + * @param output + * @param format + * @param propertyName */ - char charValue(String string) + private void appendBooleanProperty(StringBuilder output, String format, + String propertyName) { - char character; - character = string.charAt(0); - return character; + 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) + { + output.append(String.format(format, propertyName, value)); + } } @Override - public String print(SequenceI[] seqs, boolean jvsuffix) + public String print(SequenceI[] sequences, boolean jvsuffix) { + if (sequences[0].getHMM() != null) + { + hmm = sequences[0].getHMM(); + } return print(); } @@ -672,33 +644,30 @@ public class HMMFile extends AlignFile */ public String print() { - StringBuffer output = new StringBuffer(); - output.append(getFilePropertiesAsString()); + StringBuilder output = new StringBuilder(); + appendProperties(output); output.append(NL); - output.append(getModelAsString()); - output.append(NL + "//"); + appendModelAsString(output); + output.append(NL).append(TERMINATOR).append(NL); return output.toString(); } /** - * Converts the probabilities contained in a list into log space. + * Converts the probabilities contained in an array into log space * - * @param list + * @param ds */ - List convertListToLogSpace(List list) + double[] convertToLogSpace(double[] ds) { - - List convertedList = new ArrayList<>(); - for (int i = 0; i < list.size(); i++) + double[] converted = new double[ds.length]; + for (int i = 0; i < ds.length; i++) { - double prob = list.get(i); + double prob = ds[i]; double logProb = -1 * Math.log(prob); - convertedList.add(logProb); + converted[i] = logProb; } - return convertedList; - - + return converted; } /** @@ -707,30 +676,40 @@ public class HMMFile extends AlignFile @Override public SequenceI[] getSeqsAsArray() { - SequenceI hmmSeq = hmm.initHMMSequence(); + SequenceI hmmSeq = hmm.getConsensusSequence(); SequenceI[] seq = new SequenceI[1]; seq[0] = hmmSeq; return seq; + } + @Override + public void setNewlineString(String newLine) + { + NL = newLine; } - /** - * Fills symbol array and adds each symbol to an index lookup - * - * @param parser - * The scanner scanning the symbol line in the file. - */ - public void fillSymbols(Scanner parser) + @Override + public void setExportSettings(AlignExportSettingI exportSettings) { - int i = 0; - while (parser.hasNext()) - { - String strSymbol = parser.next(); - char[] symbol = strSymbol.toCharArray(); - hmm.getSymbols().add(symbol[0]); - hmm.setSymbolIndex(symbol[0], i); - i++; - } + + } + + @Override + public void configureForView(AlignmentViewPanel viewpanel) + { + + } + + @Override + public boolean hasWarningMessage() + { + return false; + } + + @Override + public String getWarningMessage() + { + return "warning message"; } }