LIMA
Libre Multilingual Analyzer — C++ API
Loading...
Searching...
No Matches
ngramMatrices.cpp
Go to the documentation of this file.
1// Copyright 2002-2020 CEA LIST
2// SPDX-FileCopyrightText: 2022 CEA LIST <gael.de-chalendar@cea.fr>
3//
4// SPDX-License-Identifier: MIT
5
15#include "ngramMatrices.h"
24
25#include <QRegularExpression>
26#include <QString>
27#include <iostream>
28
29#include <fstream>
30#include <sstream>
31#include <stdexcept>
32
33using namespace std;
34using namespace Lima::Common::MediaticData;
35
36namespace Lima
37{
38namespace LinguisticProcessing
39{
40namespace PosTagger
41{
42
44
47 Manager* manager)
48
49{
56 m_language = manager->getInitializationParameters().language;
57 m_microManager=&( static_cast<const Common::MediaticData::LanguageData&>(Common::MediaticData::MediaticData::single().mediaData(m_language)).getPropertyCodeManager().getPropertyManager("MICRO"));
58 string resourcesPath=MediaticData::single().getResourcesPath();
59 try
60 {
61 string trigramFile = Common::Misc::findFileInPaths(resourcesPath.c_str(), unitConfiguration.getParamsValueAtKey("trigramFile").c_str()).toUtf8().constData();
62 readTrigramMatrixFile(trigramFile);
63 }
65 {
66 LERROR << "no param 'trigramFile' in TrigramMatrix group for language " << (int)m_language;
68 }
69}
70
71void TrigramMatrix::readTrigramMatrixFile(const std::string& fileName)
72{
74 LINFO << "Loading trigrams matrix file: " << fileName;
75
76 std::ifstream ifl;
77 // Open the data file TriGramMatrix.dat in read mode
78 ifl.open(fileName.c_str(), std::ifstream::binary);
79
80 if (!ifl)
81 {
82 LERROR << "can't read trigrams from file " << fileName;
84 }
85
86 QRegularExpression linere("^(.+)\t(.+)\t(.+)\t(\\d+(\\.\\d+)?)$");
87 QRegularExpressionMatch what;
88 QRegularExpression numre("^\\d+$");
89
90 auto lineString = QString::fromStdString(
91 Lima::Common::Misc::readLine(ifl)).trimmed();
92 size_t linenum(0);
93 while (ifl.good() && !ifl.eof())
94 {
95 linenum++;
96 if ( (lineString.size() > 0) && (lineString[0] != '#') )
97 {
98 LinguisticCode trigram[3];
99 // QString strigram[3];
100 float proba;
101
102 what = linere.match(lineString);
103 if (what.hasMatch())
104 {
105 for (int count = 1; count <= 3; ++count)
106 {
107 QString elem = what.captured(count);
108 // strigram[count-1] = elem;
109 auto numreMatch = numre.match(elem);
110 if (numreMatch.hasMatch())
111 {
112 trigram[count-1] = LinguisticCode::fromString(elem.toStdString());
113 }
114 else
115 {
116 trigram[count-1] = m_microManager->getPropertyValue(elem.toStdString());
117 }
118 }
119
120 QString sproba = what.captured(4);
121 bool ok;
122 proba = sproba.toDouble(&ok);
123 if (!ok)
124 {
125 PTLOGINIT;
126 LERROR << "Invalid trigram line " << linenum << " in: " << fileName;
127 throw(std::runtime_error(
128 QString::fromUtf8(
129 "invalid trigram line: %1").arg(linenum).toUtf8().constData()));
130 }
131 }
132 else
133 {
134 PTLOGINIT;
135 LERROR << "Invalid trigram line " << linenum << " in: " << fileName;
136 throw(std::runtime_error(QString::fromUtf8("invalid trigram line: %1").arg(linenum).toUtf8().constData()));
137 }
138
139 // LDEBUG << "Got trigram: ["<<strigram[0]<<";"<<strigram[1]<<";"<<strigram[2]<<"]/["<<trigram[0]<<";"<<trigram[1]<<";"<<trigram[2]<<"]";
140 m_trigrams[trigram[0]][trigram[1]][trigram[2]] = proba;
141 }
142 lineString = QString::fromStdString(
143 Lima::Common::Misc::readLine(ifl)).trimmed();
144 }
145}
146
148{
149 map< LinguisticCode, map<LinguisticCode, map<LinguisticCode,float> > >::const_iterator it1=m_trigrams.find(cat1);
150 if (it1==m_trigrams.end()) return false;
151 map<LinguisticCode, map<LinguisticCode,float> >::const_iterator it2=it1->second.find(cat2);
152 if (it2==it1->second.end()) return false;
153 return (it2->second.find(cat3)!=it2->second.end());
154}
155
157{
158 map< LinguisticCode, map<LinguisticCode, map<LinguisticCode,float> > >::const_iterator it1=m_trigrams.find(cat1);
159 if (it1==m_trigrams.end()) return 0;
160 map<LinguisticCode, map<LinguisticCode,float> >::const_iterator it2=it1->second.find(cat2);
161 if (it2==it1->second.end()) return 0;
162 map<LinguisticCode, float>::const_iterator it3=it2->second.find(cat3);
163 if (it3==it2->second.end()) return 0;
164 return it3->second;
165}
166
168
171 Manager* manager)
172
173{
178 PTLOGINIT;
179 m_language = manager->getInitializationParameters().language;
180 m_microManager=&(static_cast<const Common::MediaticData::LanguageData&>(Common::MediaticData::MediaticData::single().mediaData(m_language)).getPropertyCodeManager().getPropertyManager("MICRO"));
181 string resourcesPath=MediaticData::single().getResourcesPath();
182 try
183 {
184 string trigramFile = Common::Misc::findFileInPaths(resourcesPath.c_str(), unitConfiguration.getParamsValueAtKey("bigramFile").c_str()).toUtf8().constData();
185 readBigramMatrixFile(trigramFile);
186 }
188 {
189 LERROR << "no param 'bigramFile' in BigramMatrix group for language " << (int)m_language;
190 throw InvalidConfiguration();
191 }
192}
193
194void BigramMatrix::readBigramMatrixFile(const std::string& fileName)
195{
196 PTLOGINIT;
197 LINFO << "Loading bigrams matrix file: " << fileName;
198
199 std::ifstream ifl;
200 // Open the data file TriGramMatrix.dat in read mode
201 ifl.open(fileName.c_str(), std::ifstream::binary);
202
203 if (!ifl)
204 {
205 LERROR << "can't read trigrams from file " << fileName;
206 throw InvalidConfiguration();
207 }
208
209 QRegularExpression linere("^(.+)\t(.+)\t(\\d+(\\.\\d+)?)$");
210 QRegularExpressionMatch what;
211 QRegularExpression numre("^\\d+$");
212
213 auto lineString = QString::fromStdString(
214 Lima::Common::Misc::readLine(ifl)).trimmed();
215 size_t linenum(0);
216 while (ifl.good() && !ifl.eof())
217 {
218 linenum++;
219 if ( (lineString.size() > 0) && (lineString[0] != '#') )
220 {
221 LinguisticCode bigram[2];
222 // QString sbigram[3];
223 float proba;
224
225 what = linere.match(lineString);
226 if (what.hasMatch())
227 {
228 for (int count = 1; count <= 2; ++count)
229 {
230 QString elem = what.captured(count);
231 // sbigram[count-1] = elem;
232 auto numreMatch = numre.match(elem);
233 if (numreMatch.hasMatch())
234 {
235 bigram[count-1] = LinguisticCode::fromString(elem.toStdString());
236 }
237 else
238 {
239 bigram[count-1] = m_microManager->getPropertyValue(elem.toStdString());
240 }
241 }
242
243 QString sproba = what.captured(3);
244 bool ok;
245 proba = sproba.toDouble(&ok);
246 if (!ok)
247 {
248 PTLOGINIT;
249 LERROR << "Invalid bigram line " << linenum << " in: " << fileName;
250 throw(std::runtime_error(
251 QString::fromUtf8(
252 "invalid bigram line: %1").arg(linenum).toUtf8().constData()));
253 }
254 }
255 else
256 {
257 PTLOGINIT;
258 LERROR << "Invalid bigram line " << linenum << " in: " << fileName;
259 throw(std::runtime_error(QString::fromUtf8("invalid bigram line: %1").arg(linenum).toUtf8().constData()));
260 }
261
262 // LDEBUG << "Got bigram: ["<<sbigram[0]<<";"<<sbigram[1]<<"]/["<<bigram[0]<<";"<<bigram[1]<<"]";
263 m_bigrams[bigram[0]][bigram[1]] = proba;
264 }
265 lineString = QString::fromStdString(
266 Lima::Common::Misc::readLine(ifl)).trimmed();
267 }
268}
269
271{
272 map<LinguisticCode, map<LinguisticCode,float> >::const_iterator it1=m_bigrams.find(cat1);
273 if (it1==m_bigrams.end()) return false;
274 return (it1->second.find(cat2)!=it1->second.end());
275}
276
278{
279 map<LinguisticCode, map<LinguisticCode,float> >::const_iterator it1=m_bigrams.find(cat1);
280 if (it1==m_bigrams.end()) return 0;
281 map<LinguisticCode,float>::const_iterator it2=it1->second.find(cat2);
282 if (it2==it1->second.end()) return 0;
283 return it2->second;
284}
285
286} // closing namespace PosTagger
287} // closing namespace LinguisticProcessing
288} // closing namespace Lima
#define LINFO
Definition LimaCommon.h:158
#define LERROR
Definition LimaCommon.h:161
#define PTLOGINIT
Defines a Factory to create Object of type Base.
size_t linenum(0)
int main(int argc, char *argv lineString[]) boost std::string
Definition Test.cpp:8
Holds linguistic data for one language.
const MediaData & mediaData(MediaId media) const
LinguisticCode getPropertyValue(const std::string &symbolicValue) const
Get the coded property value from the symbolic value.
return a message when a 'param' was not found
Use this exception to signal an error in one of the configuration files.
Definition LimaCommon.h:345
static LinguisticCode fromString(const std::string &str)
Definition StdBitset.h:89
void readBigramMatrixFile(const std::string &fileName)
void init(Common::XMLConfigurationFiles::GroupConfigurationStructure &unitConfiguration, AbstractResource::Manager *manager) override
initialize with parameters from configuration file.
float freq(LinguisticCode cat1, LinguisticCode cat2) const
bool exists(LinguisticCode cat1, LinguisticCode cat2) const
void readTrigramMatrixFile(const std::string &fileName)
void init(Common::XMLConfigurationFiles::GroupConfigurationStructure &unitConfiguration, AbstractResource::Manager *manager) override
initialize with parameters from configuration file.
float freq(LinguisticCode cat1, LinguisticCode cat2, LinguisticCode cat3) const
bool exists(LinguisticCode cat1, LinguisticCode cat2, LinguisticCode cat3) const
static const MediaticData & single()
const singleton accessor
Definition Singleton.h:51
std::string readLine(std::istream &inputFile)
QString findFileInPaths(const QString &paths, const QString &fileName, const QChar &separator)
Find the given file in the given paths.
SimpleFactory< AbstractResource, BigramMatrix > bigramMatrixFactory(BIGRAMMATRIX_CLASSID)
SimpleFactory< AbstractResource, TrigramMatrix > trigramMatrixFactory(TRIGRAMMATRIX_CLASSID)
NAUTITIA.
STL namespace.
Defines Bigrams and Trigrams matrices *.
#define BIGRAMMATRIX_CLASSID
#define TRIGRAMMATRIX_CLASSID
launch exception related to the configuration file parsing