lattice-compose.cc
Go to the documentation of this file.
1 // latbin/lattice-compose.cc
2 
3 // Copyright 2009-2011 Microsoft Corporation; Saarland University
4 
5 // See ../../COPYING for clarification regarding multiple authors
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 // http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
15 // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
16 // MERCHANTABLITY OR NON-INFRINGEMENT.
17 // See the Apache 2 License for the specific language governing permissions and
18 // limitations under the License.
19 
20 
21 #include "base/kaldi-common.h"
22 #include "util/common-utils.h"
23 #include "fstext/fstext-lib.h"
24 #include "lat/kaldi-lattice.h"
25 #include "lat/lattice-functions.h"
26 
27 int main(int argc, char *argv[]) {
28  try {
29  using namespace kaldi;
30  typedef kaldi::int32 int32;
31  typedef kaldi::int64 int64;
32  using fst::SymbolTable;
33  using fst::VectorFst;
34  using fst::StdArc;
35 
36  const char *usage =
37  "Composes lattices (in transducer form, as type Lattice). Depending\n"
38  "on the command-line arguments, either composes lattices with lattices,\n"
39  "or lattices with FSTs (rspecifiers are assumed to be lattices, and\n"
40  "rxfilenames are assumed to be FSTs, which have their weights interpreted\n"
41  "as \"graph weights\" when converted into the Lattice format.\n"
42  "\n"
43  "Usage: lattice-compose [options] lattice-rspecifier1 "
44  "(lattice-rspecifier2|fst-rxfilename2) lattice-wspecifier\n"
45  " e.g.: lattice-compose ark:1.lats ark:2.lats ark:composed.lats\n"
46  " or: lattice-compose ark:1.lats G.fst ark:composed.lats\n";
47 
48  ParseOptions po(usage);
49 
50  bool write_compact = true;
51  int32 num_states_cache = 50000;
52  int32 phi_label = fst::kNoLabel; // == -1
53  po.Register("write-compact", &write_compact, "If true, write in normal (compact) form.");
54  po.Register("phi-label", &phi_label, "If >0, the label on backoff arcs of the LM");
55  po.Register("num-states-cache", &num_states_cache,
56  "Number of states we cache when mapping LM FST to lattice type. "
57  "More -> more memory but faster.");
58  po.Read(argc, argv);
59 
60  if (po.NumArgs() != 3) {
61  po.PrintUsage();
62  exit(1);
63  }
64 
65  KALDI_ASSERT(phi_label > 0 || phi_label == fst::kNoLabel); // e.g. 0 not allowed.
66 
67  std::string lats_rspecifier1 = po.GetArg(1),
68  arg2 = po.GetArg(2),
69  lats_wspecifier = po.GetArg(3);
70  int32 n_done = 0, n_fail = 0;
71 
72  SequentialLatticeReader lattice_reader1(lats_rspecifier1);
73 
74  CompactLatticeWriter compact_lattice_writer;
75  LatticeWriter lattice_writer;
76 
77  if (write_compact)
78  compact_lattice_writer.Open(lats_wspecifier);
79  else
80  lattice_writer.Open(lats_wspecifier);
81 
82  if (ClassifyRspecifier(arg2, NULL, NULL) == kNoRspecifier) {
83  std::string fst_rxfilename = arg2;
84  VectorFst<StdArc> *fst2 = fst::ReadFstKaldi(fst_rxfilename);
85  // mapped_fst2 is fst2 interpreted using the LatticeWeight semiring,
86  // with all the cost on the first member of the pair (since we're
87  // assuming it's a graph weight).
88  if (fst2->Properties(fst::kILabelSorted, true) == 0) {
89  // Make sure fst2 is sorted on ilabel.
90  fst::ILabelCompare<StdArc> ilabel_comp;
91  ArcSort(fst2, ilabel_comp);
92  }
93  if (phi_label > 0)
94  PropagateFinal(phi_label, fst2);
95 
96  fst::CacheOptions cache_opts(true, num_states_cache);
97  fst::MapFstOptions mapfst_opts(cache_opts);
99  fst::MapFst<StdArc, LatticeArc, fst::StdToLatticeMapper<BaseFloat> >
100  mapped_fst2(*fst2, mapper, mapfst_opts);
101  for (; !lattice_reader1.Done(); lattice_reader1.Next()) {
102  std::string key = lattice_reader1.Key();
103  KALDI_VLOG(1) << "Processing lattice for key " << key;
104  Lattice lat1 = lattice_reader1.Value();
105  ArcSort(&lat1, fst::OLabelCompare<LatticeArc>());
106  Lattice composed_lat;
107  if (phi_label > 0) PhiCompose(lat1, mapped_fst2, phi_label, &composed_lat);
108  else Compose(lat1, mapped_fst2, &composed_lat);
109  if (composed_lat.Start() == fst::kNoStateId) {
110  KALDI_WARN << "Empty lattice for utterance " << key << " (incompatible LM?)";
111  n_fail++;
112  } else {
113  if (write_compact) {
114  CompactLattice clat;
115  ConvertLattice(composed_lat, &clat);
116  compact_lattice_writer.Write(key, clat);
117  } else {
118  lattice_writer.Write(key, composed_lat);
119  }
120  n_done++;
121  }
122  }
123  delete fst2;
124  } else {
125  std::string lats_rspecifier2 = arg2;
126  // This is the case similar to lattice-interp.cc, where we
127  // read in another set of lattices and compose them. But in this
128  // case we don't do any projection; we assume that the user has already
129  // done this (e.g. with lattice-project).
130  RandomAccessLatticeReader lattice_reader2(lats_rspecifier2);
131  for (; !lattice_reader1.Done(); lattice_reader1.Next()) {
132  std::string key = lattice_reader1.Key();
133  KALDI_VLOG(1) << "Processing lattice for key " << key;
134  Lattice lat1 = lattice_reader1.Value();
135  lattice_reader1.FreeCurrent();
136  if (!lattice_reader2.HasKey(key)) {
137  KALDI_WARN << "Not producing output for utterance " << key
138  << " because not present in second table.";
139  n_fail++;
140  continue;
141  }
142  Lattice lat2 = lattice_reader2.Value(key);
143  // Make sure that either lat2 is ilabel sorted
144  // or lat1 is olabel sorted, to ensure that
145  // composition will work.
146  if (lat2.Properties(fst::kILabelSorted, true) == 0
147  && lat1.Properties(fst::kOLabelSorted, true) == 0) {
148  // arbitrarily choose to sort lat2 rather than lat1.
149  fst::ILabelCompare<LatticeArc> ilabel_comp;
150  fst::ArcSort(&lat2, ilabel_comp);
151  }
152 
153  Lattice lat_out;
154  if (phi_label > 0) {
155  PropagateFinal(phi_label, &lat2);
156  PhiCompose(lat1, lat2, phi_label, &lat_out);
157  } else {
158  Compose(lat1, lat2, &lat_out);
159  }
160  if (lat_out.Start() == fst::kNoStateId) {
161  KALDI_WARN << "Empty lattice for utterance " << key << " (incompatible LM?)";
162  n_fail++;
163  } else {
164  if (write_compact) {
165  CompactLattice clat_out;
166  ConvertLattice(lat_out, &clat_out);
167  compact_lattice_writer.Write(key, clat_out);
168  } else {
169  lattice_writer.Write(key, lat_out);
170  }
171  n_done++;
172  }
173  }
174  }
175 
176  KALDI_LOG << "Done " << n_done << " lattices; failed for "
177  << n_fail;
178  return (n_done != 0 ? 0 : 1);
179  } catch(const std::exception &e) {
180  std::cerr << e.what();
181  return -1;
182  }
183 }
This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
Definition: chain.dox:20
bool Open(const std::string &wspecifier)
void PropagateFinal(typename Arc::Label phi_label, MutableFst< Arc > *fst)
void PrintUsage(bool print_command_line=false)
Prints the usage documentation [provided in the constructor].
fst::StdArc StdArc
void PhiCompose(const Fst< Arc > &fst1, const Fst< Arc > &fst2, typename Arc::Label phi_label, MutableFst< Arc > *ofst)
A templated class for writing objects to an archive or script file; see The Table concept...
Definition: kaldi-table.h:368
kaldi::int32 int32
void Write(const std::string &key, const T &value) const
void Register(const std::string &name, bool *ptr, const std::string &doc)
RspecifierType ClassifyRspecifier(const std::string &rspecifier, std::string *rxfilename, RspecifierOptions *opts)
Definition: kaldi-table.cc:225
Allows random access to a collection of objects in an archive or script file; see The Table concept...
Definition: kaldi-table.h:233
The class ParseOptions is for parsing command-line options; see Parsing command-line options for more...
Definition: parse-options.h:36
const T & Value(const std::string &key)
void ConvertLattice(const ExpandedFst< ArcTpl< Weight > > &ifst, MutableFst< ArcTpl< CompactLatticeWeightTpl< Weight, Int > > > *ofst, bool invert)
Convert lattice from a normal FST to a CompactLattice FST.
A templated class for reading objects sequentially from an archive or script file; see The Table conc...
Definition: kaldi-table.h:287
fst::VectorFst< LatticeArc > Lattice
Definition: kaldi-lattice.h:44
int Read(int argc, const char *const *argv)
Parses the command line options and fills the ParseOptions-registered variables.
#define KALDI_WARN
Definition: kaldi-error.h:150
std::string GetArg(int param) const
Returns one of the positional parameters; 1-based indexing for argc/argv compatibility.
int main(int argc, char *argv[])
bool HasKey(const std::string &key)
fst::VectorFst< CompactLatticeArc > CompactLattice
Definition: kaldi-lattice.h:46
int NumArgs() const
Number of positional parameters (c.f. argc-1).
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185
Class StdToLatticeMapper maps a normal arc (StdArc) to a LatticeArc by putting the StdArc weight as t...
void ReadFstKaldi(std::istream &is, bool binary, VectorFst< Arc > *fst)
#define KALDI_VLOG(v)
Definition: kaldi-error.h:156
#define KALDI_LOG
Definition: kaldi-error.h:153