/* * Copyright 1999-2004 Carnegie Mellon University. * Portions Copyright 2004 Sun Microsystems, Inc. * Portions Copyright 2004 Mitsubishi Electric Research Laboratories. * All Rights Reserved. Use is subject to license terms. * * See the file "license.terms" for information on usage and * redistribution of this file, and for a DISCLAIMER OF ALL * WARRANTIES. * */ package edu.cmu.sphinx.result; import edu.cmu.sphinx.decoder.search.AlternateHypothesisManager; import edu.cmu.sphinx.decoder.search.Token; import edu.cmu.sphinx.linguist.HMMSearchState; import edu.cmu.sphinx.linguist.SearchState; import edu.cmu.sphinx.linguist.UnitSearchState; import edu.cmu.sphinx.linguist.WordSearchState; import java.io.FileWriter; import java.io.IOException; import java.util.*; /** * Dumps out the GDL graph of all the result token chains in a Result, as well as all the alternate hypotheses along * those chains. */ public class TokenGraphDumper { private final AlternateHypothesisManager loserManager; private final Result result; private final Map<Token, Integer> tokenIDMap; private final Set<Token> dumpedTokens; private int ID; /** * Constructs a TokenGraphDumper from the given result. * * @param result The result which search space we want to dump. */ public TokenGraphDumper(Result result) { this.result = result; this.loserManager = result.getAlternateHypothesisManager(); tokenIDMap = new HashMap<Token, Integer>(); dumpedTokens = new HashSet<Token>(); } /** * Dumps the GDL output of the search space to the given file. * * @param title the title of the GDL graph * @param fileName filename to store */ public void dumpGDL(String title, String fileName) { try { System.err.println("Dumping " + title + " to " + fileName); FileWriter f = new FileWriter(fileName); f.write(dumpGDL(title)); f.close(); } catch (IOException ioe) { ioe.printStackTrace(); } } /** * Dumps the GDL output. * * @param title the title of the GDL graph * @return the GDL output string */ public String dumpGDL(String title) { StringBuilder gdl = new StringBuilder("graph: {\n"); gdl.append("title: \"").append(title).append("\"\n"); gdl.append("display_edge_labels: yes\n"); for (Token token : result.getResultTokens()) { gdl.append(dumpTokenGDL(token)); } gdl.append("}\n"); return gdl.toString(); } /** * Dumps the GDL output for a token, and any of its predecessors or alternate hypotheses. * * @param token the token to dump * @return the GDL output string */ private String dumpTokenGDL(Token token) { if (dumpedTokens.contains(token)) { return ""; } else { String label = ("[" + token.getAcousticScore() + token.getInsertionScore() + ',' + token.getLanguageScore() + ']'); if (token.isWord()) { label = token.getWord().getSpelling() + label; } String color = null; if (token.getSearchState() != null) { color = getColor(token.getSearchState()); } StringBuilder gdl = new StringBuilder().append("node: { title: \"").append(getTokenID(token)) .append("\" label: \"").append(label).append("\" color: "); if (color != null) { gdl.append(color).append(" }"); } else { gdl.append(" }"); } gdl.append('\n'); dumpedTokens.add(token); if (token.getPredecessor() != null) { gdl.append("edge: { sourcename: \"").append(getTokenID(token)) .append("\" targetname: \"").append(getTokenID(token.getPredecessor())) .append("\" }").append('\n').append(dumpTokenGDL(token.getPredecessor())); } if (loserManager != null) { List<Token> list = loserManager.getAlternatePredecessors(token); if (list != null) { for (Token loser : list) { gdl.append("edge: { sourcename: \"").append(getTokenID(token)) .append("\" targetname: \"").append(getTokenID(loser)) .append("\" }").append('\n').append(dumpTokenGDL(loser)); } } } return gdl.toString(); } } /** * Gets the color for a particular state * * @param state the state * @return its color */ private String getColor(SearchState state) { String color = "lightred"; if (state.isFinal()) { color = "magenta"; } else if (state instanceof UnitSearchState) { color = "green"; } else if (state instanceof WordSearchState) { color = "lightblue"; } else if (state instanceof HMMSearchState) { color = "orange"; } return color; } /** * Returns the next available token ID. * * @param token the token for which we want an ID * @return the next available token ID */ private Integer getTokenID(Token token) { Integer id = tokenIDMap.get(token); if (id == null) { id = ID++; tokenIDMap.put(token, id); } return id; } }