diff --git a/moses-cmd/Main.cpp b/moses-cmd/Main.cpp index 870367aaa..f224f2d8d 100644 --- a/moses-cmd/Main.cpp +++ b/moses-cmd/Main.cpp @@ -90,8 +90,8 @@ int main(int argc, char** argv) } // set number of significant decimals in output - IOWrapper::FixPrecision(cout); - IOWrapper::FixPrecision(cerr); + FixPrecision(cout); + FixPrecision(cerr); // load all the settings into the Parameter class // (stores them as strings, or array of strings) diff --git a/moses/BaseManager.cpp b/moses/BaseManager.cpp index 17bcf9627..485cdd182 100644 --- a/moses/BaseManager.cpp +++ b/moses/BaseManager.cpp @@ -9,8 +9,8 @@ using namespace std; namespace Moses { -void BaseManager::OutputAllFeatureScores(const Moses::ScoreComponentCollection &features - , std::ostream &out) +void BaseManager::OutputAllFeatureScores(const Moses::ScoreComponentCollection &features, + std::ostream &out) const { std::string lastName = ""; const vector& sff = StatefulFeatureFunction::GetStatefulFeatureFunctions(); @@ -30,10 +30,10 @@ void BaseManager::OutputAllFeatureScores(const Moses::ScoreComponentCollection & } } -void BaseManager::OutputFeatureScores( std::ostream& out - , const ScoreComponentCollection &features - , const FeatureFunction *ff - , std::string &lastName ) +void BaseManager::OutputFeatureScores( std::ostream& out, + const ScoreComponentCollection &features, + const FeatureFunction *ff, + std::string &lastName ) const { const StaticData &staticData = StaticData::Instance(); bool labeledOutput = staticData.IsLabeledNBestList(); @@ -57,6 +57,37 @@ void BaseManager::OutputFeatureScores( std::ostream& out } } +/*** + * print surface factor only for the given phrase + */ +void BaseManager::OutputSurface(std::ostream &out, const Phrase &phrase, + const std::vector &outputFactorOrder, + bool reportAllFactors) const +{ + UTIL_THROW_IF2(outputFactorOrder.size() == 0, + "Cannot be empty phrase"); + if (reportAllFactors == true) { + out << phrase; + } else { + size_t size = phrase.GetSize(); + for (size_t pos = 0 ; pos < size ; pos++) { + const Factor *factor = phrase.GetFactor(pos, outputFactorOrder[0]); + out << *factor; + UTIL_THROW_IF2(factor == NULL, + "Empty factor 0 at position " << pos); + + for (size_t i = 1 ; i < outputFactorOrder.size() ; i++) { + const Factor *factor = phrase.GetFactor(pos, outputFactorOrder[i]); + UTIL_THROW_IF2(factor == NULL, + "Empty factor " << i << " at position " << pos); + + out << "|" << *factor; + } + out << " "; + } + } } +} // namespace + diff --git a/moses/BaseManager.h b/moses/BaseManager.h index 74576fed6..0c995a596 100644 --- a/moses/BaseManager.h +++ b/moses/BaseManager.h @@ -8,16 +8,25 @@ namespace Moses { class ScoreComponentCollection; class FeatureFunction; +class OutputCollector; class BaseManager { protected: - void OutputAllFeatureScores(const Moses::ScoreComponentCollection &features - , std::ostream &out); - void OutputFeatureScores( std::ostream& out - , const ScoreComponentCollection &features - , const FeatureFunction *ff - , std::string &lastName ); + void OutputAllFeatureScores(const Moses::ScoreComponentCollection &features, + std::ostream &out) const; + void OutputFeatureScores( std::ostream& out, + const ScoreComponentCollection &features, + const FeatureFunction *ff, + std::string &lastName ) const; + void OutputSurface(std::ostream &out, + const Phrase &phrase, + const std::vector &outputFactorOrder, + bool reportAllFactors) const; + +public: + // outputs + virtual void OutputNBest(OutputCollector *collector) const = 0; }; diff --git a/moses/ChartManager.cpp b/moses/ChartManager.cpp index 173e92891..745a940de 100644 --- a/moses/ChartManager.cpp +++ b/moses/ChartManager.cpp @@ -298,7 +298,7 @@ void ChartManager::OutputSearchGraphMoses(std::ostream &outputSearchGraphStream) WriteSearchGraph(writer); } -void ChartManager::OutputNBest(OutputCollector *collector) +void ChartManager::OutputNBest(OutputCollector *collector) const { const StaticData &staticData = StaticData::Instance(); size_t nBestSize = staticData.GetNBestSize(); @@ -316,15 +316,9 @@ void ChartManager::OutputNBest(OutputCollector *collector) } -void FixPrecision(std::ostream &stream, size_t size = 3) -{ - stream.setf(std::ios::fixed); - stream.precision(size); -} - void ChartManager::OutputNBestList(OutputCollector *collector, const ChartKBestExtractor::KBestVec &nBestList, - long translationId) + long translationId) const { const StaticData &staticData = StaticData::Instance(); const std::vector &outputFactorOrder = staticData.GetOutputFactorOrder(); @@ -386,36 +380,7 @@ void ChartManager::OutputNBestList(OutputCollector *collector, collector->Write(translationId, out.str()); } -/*** - * print surface factor only for the given phrase - */ -void ChartManager::OutputSurface(std::ostream &out, const Phrase &phrase, const std::vector &outputFactorOrder, bool reportAllFactors) -{ - UTIL_THROW_IF2(outputFactorOrder.size() == 0, - "Cannot be empty phrase"); - if (reportAllFactors == true) { - out << phrase; - } else { - size_t size = phrase.GetSize(); - for (size_t pos = 0 ; pos < size ; pos++) { - const Factor *factor = phrase.GetFactor(pos, outputFactorOrder[0]); - out << *factor; - UTIL_THROW_IF2(factor == NULL, - "Empty factor 0 at position " << pos); - - for (size_t i = 1 ; i < outputFactorOrder.size() ; i++) { - const Factor *factor = phrase.GetFactor(pos, outputFactorOrder[i]); - UTIL_THROW_IF2(factor == NULL, - "Empty factor " << i << " at position " << pos); - - out << "|" << *factor; - } - out << " "; - } - } -} - -size_t ChartManager::CalcSourceSize(const Moses::ChartHypothesis *hypo) +size_t ChartManager::CalcSourceSize(const Moses::ChartHypothesis *hypo) const { size_t ret = hypo->GetCurrSourceRange().GetNumWordsCovered(); const std::vector &prevHypos = hypo->GetPrevHypos(); @@ -429,7 +394,7 @@ size_t ChartManager::CalcSourceSize(const Moses::ChartHypothesis *hypo) size_t ChartManager::OutputAlignmentNBest( Alignments &retAlign, const Moses::ChartKBestExtractor::Derivation &derivation, - size_t startTarget) + size_t startTarget) const { const ChartHypothesis &hypo = derivation.edge.head->hypothesis; diff --git a/moses/ChartManager.h b/moses/ChartManager.h index 849101b5d..80f6586bb 100644 --- a/moses/ChartManager.h +++ b/moses/ChartManager.h @@ -41,7 +41,6 @@ namespace Moses class ChartHypothesis; class ChartSearchGraphWriter; -class OutputCollector; /** Holds everything you need to decode 1 sentence with the hierachical/syntax decoder */ @@ -68,15 +67,14 @@ private: void OutputNBestList(OutputCollector *collector, const ChartKBestExtractor::KBestVec &nBestList, - long translationId); - void OutputSurface(std::ostream &out, const Phrase &phrase, const std::vector &outputFactorOrder, bool reportAllFactors); - size_t CalcSourceSize(const Moses::ChartHypothesis *hypo); + long translationId) const; + size_t CalcSourceSize(const Moses::ChartHypothesis *hypo) const; size_t OutputAlignmentNBest(Alignments &retAlign, const Moses::ChartKBestExtractor::Derivation &derivation, - size_t startTarget); + size_t startTarget) const; template - void ShiftOffsets(std::vector &offsets, T shift) + void ShiftOffsets(std::vector &offsets, T shift) const { T currPos = shift; for (size_t i = 0; i < offsets.size(); ++i) { @@ -138,7 +136,7 @@ public: const ChartParser &GetParser() const { return m_parser; } // outputs - void OutputNBest(OutputCollector *collector); + void OutputNBest(OutputCollector *collector) const; }; } diff --git a/moses/IOWrapper.cpp b/moses/IOWrapper.cpp index 057a10600..becde9b65 100644 --- a/moses/IOWrapper.cpp +++ b/moses/IOWrapper.cpp @@ -258,12 +258,6 @@ GetInput(InputType* inputType) } } -void IOWrapper::FixPrecision(std::ostream &stream, size_t size) -{ - stream.setf(std::ios::fixed); - stream.precision(size); -} - std::map IOWrapper::GetPlaceholders(const Hypothesis &hypo, FactorType placeholderFactor) { const InputPath &inputPath = hypo.GetTranslationOption().GetInputPath(); @@ -628,34 +622,6 @@ void IOWrapper::OutputTreeFragmentsTranslationOptions(std::ostream &out, Applica } } -void IOWrapper::OutputNBestList(const std::vector &nbest, long translationId) -{ - std::ostringstream out; - // wtf? copied from the original OutputNBestList - if (m_nBestOutputCollector->OutputIsCout()) { - FixPrecision(out); - } - Phrase outputPhrase; - ScoreComponentCollection features; - for (std::vector::const_iterator i = nbest.begin(); i != nbest.end(); ++i) { - Incremental::PhraseAndFeatures(*i, outputPhrase, features); - // and - UTIL_THROW_IF2(outputPhrase.GetSize() < 2, - "Output phrase should have contained at least 2 words (beginning and end-of-sentence)"); - - outputPhrase.RemoveWord(0); - outputPhrase.RemoveWord(outputPhrase.GetSize() - 1); - out << translationId << " ||| "; - OutputSurface(out, outputPhrase, *m_outputFactorOrder, false); - out << " ||| "; - OutputAllFeatureScores(features, out); - out << " ||| " << i->GetScore() << '\n'; - } - out << std::flush; - assert(m_nBestOutputCollector); - m_nBestOutputCollector->Write(translationId, out.str()); -} - /*** * print surface factor only for the given phrase */ @@ -1353,7 +1319,7 @@ void IOWrapper::OutputBestHypo(const Syntax::SHyperedge *best, return; } std::ostringstream out; - IOWrapper::FixPrecision(out); + FixPrecision(out); if (best == NULL) { VERBOSE(1, "NO BEST TRANSLATION" << std::endl); if (StaticData::Instance().GetOutputHypoScore()) { @@ -1383,7 +1349,7 @@ void IOWrapper::OutputNBestList( if (m_nBestOutputCollector->OutputIsCout()) { // Set precision only if we're writing the n-best list to cout. This is to // preserve existing behaviour, but should probably be done either way. - IOWrapper::FixPrecision(out); + FixPrecision(out); } bool includeWordAlignment = diff --git a/moses/IOWrapper.h b/moses/IOWrapper.h index 51f515c53..17781b2ac 100644 --- a/moses/IOWrapper.h +++ b/moses/IOWrapper.h @@ -157,8 +157,6 @@ protected: } public: - static void FixPrecision(std::ostream &, size_t size=3); - IOWrapper(); ~IOWrapper(); @@ -209,7 +207,6 @@ public: void OutputBestNone(long translationId); void OutputNBestList(const std::vector > &nBestList, long translationId); - void OutputNBestList(const std::vector &nbest, long translationId); void OutputNBestList(const Moses::Syntax::KBestExtractor::KBestVec &nBestList, long translationId); void OutputDetailedTranslationReport(const Moses::ChartHypothesis *hypo, const Moses::Sentence &sentence, long translationId); diff --git a/moses/Incremental.cpp b/moses/Incremental.cpp index 06c46b786..d366065a5 100644 --- a/moses/Incremental.cpp +++ b/moses/Incremental.cpp @@ -8,6 +8,7 @@ #include "moses/StaticData.h" #include "moses/Util.h" #include "moses/LM/Base.h" +#include "moses/OutputCollector.h" #include "lm/model.hh" #include "search/applied.hh" @@ -278,6 +279,47 @@ const std::vector &Manager::ProcessSentence() return *completed_nbest_; } +void Manager::OutputNBest(OutputCollector *collector) const +{ + if (collector == NULL) { + return; + } + + OutputNBestList(collector, *completed_nbest_, source_.GetTranslationId()); +} + +void Manager::OutputNBestList(OutputCollector *collector, const std::vector &nbest, long translationId) const +{ + const StaticData &staticData = StaticData::Instance(); + const std::vector &outputFactorOrder = staticData.GetOutputFactorOrder(); + + std::ostringstream out; + // wtf? copied from the original OutputNBestList + if (collector->OutputIsCout()) { + FixPrecision(out); + } + Phrase outputPhrase; + ScoreComponentCollection features; + for (std::vector::const_iterator i = nbest.begin(); i != nbest.end(); ++i) { + Incremental::PhraseAndFeatures(*i, outputPhrase, features); + // and + UTIL_THROW_IF2(outputPhrase.GetSize() < 2, + "Output phrase should have contained at least 2 words (beginning and end-of-sentence)"); + + outputPhrase.RemoveWord(0); + outputPhrase.RemoveWord(outputPhrase.GetSize() - 1); + out << translationId << " ||| "; + OutputSurface(out, outputPhrase, outputFactorOrder, false); + out << " ||| "; + OutputAllFeatureScores(features, out); + out << " ||| " << i->GetScore() << '\n'; + } + out << std::flush; + assert(collector); + collector->Write(translationId, out.str()); +} + + namespace { diff --git a/moses/Incremental.h b/moses/Incremental.h index d3d317244..35d418fd3 100644 --- a/moses/Incremental.h +++ b/moses/Incremental.h @@ -37,6 +37,10 @@ public: return *completed_nbest_; } + // output + void OutputNBest(OutputCollector *collector) const; + + private: template search::History PopulateBest(const Model &model, const std::vector &words, Best &out); @@ -53,6 +57,9 @@ private: search::NBest n_best_; const std::vector *completed_nbest_; + + // outputs + void OutputNBestList(OutputCollector *collector, const std::vector &nbest, long translationId) const; }; // Just get the phrase. diff --git a/moses/Manager.cpp b/moses/Manager.cpp index c0e2d62ef..4d01d5e09 100644 --- a/moses/Manager.cpp +++ b/moses/Manager.cpp @@ -1448,7 +1448,7 @@ SentenceStats& Manager::GetSentenceStats() const } -void Manager::OutputNBest(OutputCollector *collector) +void Manager::OutputNBest(OutputCollector *collector) const { const StaticData &staticData = StaticData::Instance(); @@ -1467,7 +1467,7 @@ void Manager::OutputNBest(std::ostream& out , const Moses::TrellisPathList &nBestList , const std::vector& outputFactorOrder , long translationId - , char reportSegmentation) + , char reportSegmentation) const { const StaticData &staticData = StaticData::Instance(); bool reportAllFactors = staticData.GetReportAllFactorsNBest(); @@ -1542,7 +1542,7 @@ void Manager::OutputNBest(std::ostream& out * print surface factor only for the given phrase */ void Manager::OutputSurface(std::ostream &out, const Hypothesis &edge, const std::vector &outputFactorOrder, - char reportSegmentation, bool reportAllFactors) + char reportSegmentation, bool reportAllFactors) const { UTIL_THROW_IF2(outputFactorOrder.size() == 0, "Must specific at least 1 output factor"); @@ -1614,7 +1614,7 @@ void Manager::OutputSurface(std::ostream &out, const Hypothesis &edge, const std } } -void Manager::OutputAlignment(ostream &out, const AlignmentInfo &ai, size_t sourceOffset, size_t targetOffset) +void Manager::OutputAlignment(ostream &out, const AlignmentInfo &ai, size_t sourceOffset, size_t targetOffset) const { typedef std::vector< const std::pair* > AlignVec; AlignVec alignments = ai.GetSortedAlignments(); @@ -1627,7 +1627,7 @@ void Manager::OutputAlignment(ostream &out, const AlignmentInfo &ai, size_t sour } -void Manager::OutputInput(std::ostream& os, const Hypothesis* hypo) +void Manager::OutputInput(std::ostream& os, const Hypothesis* hypo) const { size_t len = hypo->GetInput().GetSize(); std::vector inp_phrases(len, 0); @@ -1636,7 +1636,7 @@ void Manager::OutputInput(std::ostream& os, const Hypothesis* hypo) if (inp_phrases[i]) os << *inp_phrases[i]; } -void Manager::OutputInput(std::vector& map, const Hypothesis* hypo) +void Manager::OutputInput(std::vector& map, const Hypothesis* hypo) const { if (hypo->GetPrevHypo()) { OutputInput(map, hypo->GetPrevHypo()); @@ -1644,7 +1644,7 @@ void Manager::OutputInput(std::vector& map, const Hypothesis* hyp } } -std::map Manager::GetPlaceholders(const Hypothesis &hypo, FactorType placeholderFactor) +std::map Manager::GetPlaceholders(const Hypothesis &hypo, FactorType placeholderFactor) const { const InputPath &inputPath = hypo.GetTranslationOption().GetInputPath(); const Phrase &inputPhrase = inputPath.GetPhrase(); @@ -1664,7 +1664,7 @@ std::map Manager::GetPlaceholders(const Hypothesis &hypo, return ret; } -void Manager::OutputLatticeSamples(OutputCollector *collector) +void Manager::OutputLatticeSamples(OutputCollector *collector) const { const StaticData &staticData = StaticData::Instance(); if (collector) { diff --git a/moses/Manager.h b/moses/Manager.h index e402c05a6..b078c5c8c 100644 --- a/moses/Manager.h +++ b/moses/Manager.h @@ -42,7 +42,6 @@ namespace Moses class SentenceStats; class TrellisPath; class TranslationOptionCollection; -class OutputCollector; /** Used to output the search graph */ struct SearchGraphNode { @@ -134,13 +133,13 @@ protected: , const Moses::TrellisPathList &nBestList , const std::vector& outputFactorOrder , long translationId - , char reportSegmentation); + , char reportSegmentation) const; void OutputSurface(std::ostream &out, const Hypothesis &edge, const std::vector &outputFactorOrder, - char reportSegmentation, bool reportAllFactors); - void OutputAlignment(std::ostream &out, const AlignmentInfo &ai, size_t sourceOffset, size_t targetOffset); - void OutputInput(std::ostream& os, const Hypothesis* hypo); - void OutputInput(std::vector& map, const Hypothesis* hypo); - std::map GetPlaceholders(const Hypothesis &hypo, FactorType placeholderFactor); + char reportSegmentation, bool reportAllFactors) const; + void OutputAlignment(std::ostream &out, const AlignmentInfo &ai, size_t sourceOffset, size_t targetOffset) const; + void OutputInput(std::ostream& os, const Hypothesis* hypo) const; + void OutputInput(std::vector& map, const Hypothesis* hypo) const; + std::map GetPlaceholders(const Hypothesis &hypo, FactorType placeholderFactor) const; public: InputType const& m_source; /**< source sentence to be translated */ @@ -186,8 +185,8 @@ public: std::vector< const Hypothesis* >* pConnectedList, std::map < const Hypothesis*, std::set < const Hypothesis* > >* pOutgoingHyps, std::vector< float>* pFwdBwdScores) const; // outputs - void OutputNBest(OutputCollector *collector); - void OutputLatticeSamples(OutputCollector *collector); + void OutputNBest(OutputCollector *collector) const; + void OutputLatticeSamples(OutputCollector *collector) const; }; } diff --git a/moses/TranslationTask.cpp b/moses/TranslationTask.cpp index 4b0826368..a39766180 100644 --- a/moses/TranslationTask.cpp +++ b/moses/TranslationTask.cpp @@ -92,7 +92,7 @@ void TranslationTask::RunPb() // output word graph if (m_ioWrapper.GetWordGraphCollector()) { ostringstream out; - fix(out,PRECISION); + FixPrecision(out,PRECISION); manager.GetWordGraph(m_source->GetTranslationId(), out); m_ioWrapper.GetWordGraphCollector()->Write(m_source->GetTranslationId(), out.str()); } @@ -100,7 +100,7 @@ void TranslationTask::RunPb() // output search graph if (m_ioWrapper.GetSearchGraphOutputCollector()) { ostringstream out; - fix(out,PRECISION); + FixPrecision(out,PRECISION); manager.OutputSearchGraph(m_source->GetTranslationId(), out); m_ioWrapper.GetSearchGraphOutputCollector()->Write(m_source->GetTranslationId(), out.str()); @@ -128,7 +128,7 @@ void TranslationTask::RunPb() file->open(fileName.str().c_str()); if (file->is_open() && file->good()) { ostringstream out; - fix(out,PRECISION); + FixPrecision(out,PRECISION); manager.OutputSearchGraphAsSLF(m_source->GetTranslationId(), out); *file << out.str(); file -> flush(); @@ -149,7 +149,7 @@ void TranslationTask::RunPb() if (m_ioWrapper.GetSingleBestOutputCollector()) { ostringstream out; ostringstream debug; - fix(debug,PRECISION); + FixPrecision(debug,PRECISION); // all derivations - send them to debug stream if (staticData.PrintAllDerivations()) { @@ -283,7 +283,7 @@ void TranslationTask::RunPb() // detailed translation reporting if (m_ioWrapper.GetDetailedTranslationCollector()) { ostringstream out; - fix(out,PRECISION); + FixPrecision(out,PRECISION); TranslationAnalysis::PrintTranslationAnalysis(out, manager.GetBestHypothesis()); m_ioWrapper.GetDetailedTranslationCollector()->Write(m_source->GetTranslationId(),out.str()); } @@ -348,8 +348,9 @@ void TranslationTask::RunChart() } else { m_ioWrapper.OutputBestNone(translationId); } - if (staticData.GetNBestSize() > 0) - m_ioWrapper.OutputNBestList(nbest, translationId); + + manager.OutputNBest(m_ioWrapper.GetNBestOutputCollector()); + return; } diff --git a/moses/Util.cpp b/moses/Util.cpp index 9664c811e..9ad615861 100644 --- a/moses/Util.cpp +++ b/moses/Util.cpp @@ -220,7 +220,7 @@ void PrintFeatureWeight(const FeatureFunction* ff) void ShowWeights() { - fix(cout,6); + FixPrecision(cout,6); const vector& slf = StatelessFeatureFunction::GetStatelessFeatureFunctions(); const vector& sff = StatefulFeatureFunction::GetStatefulFeatureFunctions(); diff --git a/moses/Util.h b/moses/Util.h index 74a130b9e..4d2ccea10 100644 --- a/moses/Util.h +++ b/moses/Util.h @@ -478,7 +478,7 @@ T log_sum (T log_a, T log_b) } /** Enforce rounding */ -inline void fix(std::ostream& stream, size_t size) +inline void FixPrecision(std::ostream& stream, size_t size = 3) { stream.setf(std::ios::fixed); stream.precision(size);