LIMA
Libre Multilingual Analyzer — C++ API
Loading...
Searching...
No Matches
DepTripletLogger.cpp
Go to the documentation of this file.
1// Copyright 2002-2013 CEA LIST
2// SPDX-FileCopyrightText: 2022 CEA LIST <gael.de-chalendar@cea.fr>
3//
4// SPDX-License-Identifier: MIT
5
6/***************************************************************************
7 * Copyright (C) 2004-2012 by CEA LIST *
8 * *
9 ***************************************************************************/
10#include "DepTripletLogger.h"
11
30
31#include <fstream>
32#include <deque>
33#include <queue>
34#include <algorithm>
35
36
37using namespace std;
38using namespace boost;
39using namespace boost::tuples;
40
42using namespace Lima::Common::MediaticData;
43using namespace Lima::Common::BagOfWords;
44using namespace Lima::Common::AnnotationGraphs;
45
46using namespace Lima::LinguisticProcessing;
50
51namespace Lima
52{
53namespace LinguisticProcessing
54{
55namespace SyntacticAnalysis
56{
57
59
62{
63 m_bowGenerator = new BowGenerator();
64}
65
66
68{
69 delete m_bowGenerator;
70}
71
74 Manager* manager)
75{
76 m_language=manager->getInitializationParameters().media;
77 std::deque<std::string> relation_names;
78
79 try
80 {
81 relation_names=unitConfiguration.getListsValueAtKey("selectedDependency");
82 }
83 catch (NoSuchList& )
84 {
85 // empty display
86 }
87 for( std::deque<std::string>::iterator src = relation_names.begin() ; src != relation_names.end() ; src++ )
88 {
89 m_relation_names.insert(*src);
90 }
91
92
93 m_macroAccessor=&(static_cast<const Common::MediaticData::LanguageData&>(Common::MediaticData::MediaticData::single().mediaData(m_language)).getPropertyCodeManager().getPropertyAccessor("MACRO"));
94 m_microAccessor=&(static_cast<const Common::MediaticData::LanguageData&>(Common::MediaticData::MediaticData::single().mediaData(m_language)).getPropertyCodeManager().getPropertyAccessor("MICRO"));
95
96 m_bowGenerator->init(unitConfiguration, m_language);
97}
98
100 AnalysisContent& analysis) const
101{
103 SALOGINIT;
104 auto metadata = std::dynamic_pointer_cast<LinguisticMetaData>(analysis.getData("LinguisticMetaData"));
105 if (metadata == 0)
106 {
107 LERROR << "no LinguisticMetaData ! abort";
108 return MISSING_DATA;
109 }
110 auto anagraph = std::dynamic_pointer_cast<AnalysisGraph>(analysis.getData("AnalysisGraph"));
111 if (anagraph==0)
112 {
113 LERROR << "no AnalysisGraph ! abort";
114 return MISSING_DATA;
115 }
116 auto posgraph = std::dynamic_pointer_cast<AnalysisGraph>(analysis.getData("PosGraph"));
117 if (posgraph==0)
118 {
119 LERROR << "no PosGraph ! abort";
120 return MISSING_DATA;
121 }
122 auto syntacticData = std::dynamic_pointer_cast<SyntacticData>(analysis.getData("SyntacticData"));
123 if (syntacticData==0)
124 {
125 syntacticData = std::make_shared<SyntacticData>(posgraph.get(), nullptr);
126 syntacticData->setupDependencyGraph();
127 analysis.setData("SyntacticData",syntacticData);
128 }
129 auto annotationData = std::dynamic_pointer_cast< AnnotationData >(analysis.getData("AnnotationData"));
130 if (annotationData==0)
131 {
132 LERROR << "no annotation graph available !";
133 return MISSING_DATA;
134 }
135
136 std::ofstream outputStream;
137 if (!openLogFile(outputStream,metadata->getMetaData("FileName")))
138 {
139 SALOGINIT;
140 LERROR << "Can't open log file ";
142 }
143
144 VxToTermsMap compoundsHeads = getCompoundsHeads(annotationData.get(),
145 syntacticData.get(), analysis, posgraph.get(), *(anagraph->getGraph()),
146 *(posgraph->getGraph()));
147 dumpDependencyRelations(outputStream, *(anagraph->getGraph()),
148 *(posgraph->getGraph()), syntacticData.get(),
149 annotationData.get(), compoundsHeads);
150
151 // delete syntacticData;
152
153 TimeUtils::logElapsedTime("DepTripletLogger");
154 return SUCCESS_ID;
155}
156
157
158void DepTripletLogger::dumpDependencyRelations(std::ostream& outputStream,
159 const LinguisticGraph& anagraph,
160 const LinguisticGraph& posgraph,
161 const SyntacticData* syntData,
162 const AnnotationData* annotationData,
163 const VxToTermsMap& compoundsHeads) const
164{
165 SALOGINIT;
166 LDEBUG << "Address of syntactic data used to dump: " << syntData;
167 const DependencyGraph* depGraph = syntData-> dependencyGraph();
168 LDEBUG << "Address of dependency graph used to dump: " << depGraph;
169
170
171 const LinguisticGraph* graph = syntData->graph();
172 CVertexDataPropertyMap dataMap = get(vertex_data, *graph);
173// const FsaStringsPool& sp=Common::MediaticData::MediaticData::single().stringsPool(m_language);
174
175 DependencyGraphEdgeIt it, it_end;
176 boost::tie(it, it_end) = edges(*depGraph);
177 for (; it != it_end; it++)
178 {
179 LDEBUG << "Dumping dependency edge " << source(*it, *depGraph) << " -> " << target(*it, *depGraph);
180 try
181 {
182 LDEBUG << "DepTripletLogger::dumpDependencyRelations";
183 CEdgeDepRelTypePropertyMap typeMap = get(edge_deprel_type, *depGraph);
185 LDEBUG << "DepTripletLogger::dumpDependencyRelations relation = "
186 << static_cast<const Common::MediaticData::LanguageData&>(Common::MediaticData::MediaticData::single().mediaData(m_language)).getSyntacticRelationName(type);
187 std::set<std::string>::const_iterator relationPos =
188 m_relation_names.find(static_cast<const Common::MediaticData::LanguageData&>(Common::MediaticData::MediaticData::single().mediaData(m_language)).getSyntacticRelationName(type));
189 if( relationPos != m_relation_names.end() )
190 {
191 LDEBUG << "Src : Dep vertex= " << source(*it, *depGraph);
192 LinguisticGraphVertex src = syntData->tokenVertexForDepVertex(source(*it, *depGraph));
193 LDEBUG << "Src : Morph vertex= " << src;
194 LDEBUG << "Targ : Dep vertex= " << target(*it, *depGraph) ;
195 LinguisticGraphVertex dest = syntData->tokenVertexForDepVertex(target(*it, *depGraph));
196 LDEBUG << "Targ : Morph vertex= " << dest;
197
198 std::set<StringsPoolIndex> srcLemmas=dataMap[src]->allLemma();
199 std::set<StringsPoolIndex> destLemmas=dataMap[dest]->allLemma();
200
201/* for (set<StringsPoolIndex>::const_iterator srcItr=srcLemmas.begin();
202 srcItr!=srcLemmas.end();
203 srcItr++)
204 {
205 for (set<StringsPoolIndex>::const_iterator destItr=destLemmas.begin();
206 destItr!=destLemmas.end();
207 destItr++)
208 {
209 outputStream << sp[*srcItr] << "#" << *relationPos << "#" << sp[*destItr] << std::endl;
210 }
211 }*/
212 dumpDepWithCompounds(outputStream, anagraph, posgraph, syntData,
213 annotationData, src, dest,
214 *relationPos, compoundsHeads);
215 }
216 else
217 {
218 LDEBUG << "DepTripletLogger::dumpDependencyRelations: dump nothing..";
219 }
220 }
221 catch (const std::range_error& )
222 {
223 }
224 catch (...)
225 {
226 LDEBUG << "DepTripletLogger::dumpDependencyRelations: catch others.....";
227 throw;
228 }
229 }
230}
231
232
233void DepTripletLogger::dumpDepWithCompounds(
234 std::ostream& outputStream,
235 const LinguisticGraph& anagraph,
236 const LinguisticGraph& posgraph,
237 const SyntacticData* syntData,
238 const AnnotationData* annotationData,
241 const std::string& rel,
242 const VxToTermsMap& compoundsHeads) const
243{
244 LIMA_UNUSED(syntData);
245// CVertexDataPropertyMap dataMap = get(vertex_data, posgraph);
246
247 std::set< LinguisticGraphVertex > visited;
248 std::vector< std::pair< boost::shared_ptr< Common::BagOfWords::BoWRelation > , boost::shared_ptr< Common::BagOfWords::AbstractBoWElement > > > srcTokens =
249 m_bowGenerator->createAbstractBoWElement(src, anagraph, posgraph, 0, annotationData, visited);
250 std::vector< std::pair< boost::shared_ptr< Common::BagOfWords::BoWRelation >, boost::shared_ptr< Common::BagOfWords::AbstractBoWElement > > > destTokens =
251 m_bowGenerator->createAbstractBoWElement(dest, anagraph, posgraph, 0, annotationData, visited);
252
253 std::map<std::string, std::set<LinguisticGraphVertex> > srcs, dests;
254
255 for (auto srcItr=srcTokens.begin();
256 srcItr!=srcTokens.end();
257 srcItr++)
258 {
259 std::set<LinguisticGraphVertex> theSet;
260// std::cerr << "collecting vertices for " << (*srcItr)->getOutputUTF8String() << std::endl;
261// std::cerr << " inserting " << src << std::endl;
262 theSet.insert(src);
263 srcs.insert(std::make_pair((*srcItr).second->getOutputUTF8String(),theSet));
264 }
265 if (compoundsHeads.find(src) != compoundsHeads.end())
266 {
267 auto it = (*(compoundsHeads.find(src))).second.begin(),
268 it_end = (*(compoundsHeads.find(src))).second.end();
269 for (; it != it_end; it++)
270 {
271 std::ostringstream oss;
272 oss << (*it)->getOutputUTF8String();
273 std::set<LinguisticGraphVertex> theSet;
274// std::cerr << "collectiong vertices for " << **it << std::endl;
275 collectVertices(theSet, *it);
276 srcs.insert(std::make_pair(oss.str(), theSet));
277 }
278 }
279
280 for (auto destItr=destTokens.begin();
281 destItr!=destTokens.end();
282 destItr++)
283 {
284 std::set<LinguisticGraphVertex> theSet;
285// std::cerr << "collectiong vertices for " << (*destItr)->getOutputUTF8String() << std::endl;
286// std::cerr << " inserting " << dest << std::endl;
287 theSet.insert(dest);
288 dests.insert(std::make_pair((*destItr).second->getOutputUTF8String(),theSet));
289 }
290 if (compoundsHeads.find(dest) != compoundsHeads.end())
291 {
292 auto it = (*(compoundsHeads.find(dest))).second.begin(),
293 it_end = (*(compoundsHeads.find(dest))).second.end();
294 for (; it != it_end; it++)
295 {
296 std::ostringstream oss;
297 oss << (*it)->getOutputUTF8String();
298 std::set<LinguisticGraphVertex> theSet;
299// std::cerr << "collectiong vertices for " << **it << std::endl;
300 collectVertices(theSet, *it);
301 dests.insert(std::make_pair(oss.str(),theSet));
302 }
303 }
304
305 for (
306 std::map<std::string, std::set<LinguisticGraphVertex> >::const_iterator sit = srcs.begin();
307 sit != srcs.end();
308 sit++
309 )
310 {
311 for (
312 std::map<std::string, std::set<LinguisticGraphVertex> >::const_iterator dit = dests.begin();
313 dit != dests.end();
314 dit++
315 )
316 {
317 std::set<LinguisticGraphVertex> intersection;
318 std::insert_iterator<std::set<LinguisticGraphVertex> > ii(intersection, intersection.begin());
319 std::set_intersection( (*sit).second.begin(), (*sit).second.end(),
320 (*dit).second.begin(), (*dit).second.end(),
321 ii);
322 if (intersection.empty())
323 {
324 outputStream << (*sit).first << "#" << rel << "#" << (*dit).first << std::endl;
325 }
326 }
327 }
328}
329
330VxToTermsMap DepTripletLogger::getCompoundsHeads(
331 const Common::AnnotationGraphs::AnnotationData* annotationData,
332 const SyntacticData* syntacticData,
333 AnalysisContent& analysis,
334 AnalysisGraph* posAgraph,
335 const LinguisticGraph& anagraph,
336 const LinguisticGraph& posgraph) const
337{
338 LIMA_UNUSED(analysis);
339 SALOGINIT;
340 LDEBUG << "DepTripletDumper: ========================================";
341 LDEBUG << "DepTripletDumper: getting compounds heads";
342 const LinguisticGraphVertex begin = posAgraph->firstVertex();
343 const LinguisticGraphVertex end = posAgraph->lastVertex();
344
345 VxToTermsMap result;
346
347 // go through the graph, add BoWTokens that are not in complex terms
348 // Don't use visitor to avoid throwing exceptions
349
350 LinguisticGraphVertex firstVx = posAgraph->firstVertex();
351 LinguisticGraphVertex lastVx = posAgraph->lastVertex();
352
353 std::set< std::string > alreadyStored;
354 std::set<LinguisticGraphVertex> visited;
355 std::queue<LinguisticGraphVertex> toVisit;
356 toVisit.push(begin);
357
358 LinguisticGraphOutEdgeIt outItr,outItrEnd;
359 while (!toVisit.empty())
360 {
361 LinguisticGraphVertex v=toVisit.front();
362 toVisit.pop();
363 if (v == end) {
364 continue;
365 }
366
367 for (boost::tie(outItr,outItrEnd)=out_edges(v,posgraph);
368 outItr!=outItrEnd;
369 outItr++)
370 {
371 LinguisticGraphVertex next=target(*outItr,posgraph);
372 if (visited.find(next)==visited.end())
373 {
374 visited.insert(next);
375 toVisit.push(next);
376 }
377 }
378
379 if (v != firstVx && v != lastVx)
380 {
382// LDEBUG << "hasAnnotation("<<v<<", CompoundTokenAnnotation): "
383// << annotationData->hasAnnotation(v, Common::Misc::utf8stdstring2limastring("CompoundTokenAnnotation"));
384// LDEBUG << "hasAnnotation("<<v<<", SpecificEntity): "
385// << annotationData->hasAnnotation(v, Common::Misc::utf8stdstring2limastring("SpecificEntity"));
386 //std::set< uint32_t > cpdsHeads = annotationData->matches("PosGraph", v, "cpdHead");
387 std::set< AnnotationGraphVertex > cpdsHeads = annotationData->matches("PosGraph", v, "cpdHead");
388 if (!cpdsHeads.empty())
389 {
390 std::set< AnnotationGraphVertex >::const_iterator cpdsHeadsIt, cpdsHeadsIt_end;
391 cpdsHeadsIt = cpdsHeads.begin(); cpdsHeadsIt_end = cpdsHeads.end();
392 for (; cpdsHeadsIt != cpdsHeadsIt_end; cpdsHeadsIt++)
393 {
394 AnnotationGraphVertex agv = *cpdsHeadsIt;
395 std::vector<std::pair<boost::shared_ptr< BoWRelation >, boost::shared_ptr< BoWToken > > > bowTokens =
396 m_bowGenerator->buildTermFor(agv, agv, anagraph, posgraph, 0,
397 syntacticData, annotationData, visited);
398 for (auto bowItr=bowTokens.begin();
399 bowItr!=bowTokens.end();
400 bowItr++)
401 {
402 std::string elem = (*bowItr).second->getIdUTF8String();
403 if (alreadyStored.find(elem) != alreadyStored.end())
404 { // already stored
405 // LDEBUG << "BuildBoWTokenListVisitor: BoWToken already stored. Skipping it.";
406 }
407 else
408 {
409 boost::shared_ptr< BoWTerm > bt = boost::dynamic_pointer_cast<BoWTerm>((*bowItr).second);
410 if (bt != 0)
411 {
412 getCompoundsHeads(result, &*bt);
413 }
414 alreadyStored.insert(elem);
415 }
416 }
417 }
418 }
419 else
420 {
421 std::vector<std::pair< boost::shared_ptr< BoWRelation >, boost::shared_ptr< AbstractBoWElement > > > bowTokens=m_bowGenerator->createAbstractBoWElement(v, anagraph, posgraph, 0, annotationData, visited);
422
423 for (auto bowItr=bowTokens.begin();
424 bowItr!=bowTokens.end();
425 bowItr++)
426 {
427 std::string elem = (*bowItr).second->getIdUTF8String();
428 if (alreadyStored.find(elem) != alreadyStored.end())
429 { // already stored
430 // LDEBUG << "BuildBoWTokenListVisitor: BoWToken already stored. Skipping it.";
431 }
432 else
433 {
434 boost::shared_ptr< BoWTerm > bt = boost::dynamic_pointer_cast< BoWTerm >((*bowItr).second);
435 if (bt != 0)
436 {
437 getCompoundsHeads(result, &*bt);
438 }
439 alreadyStored.insert(elem);
440 }
441 }
442 }
443 }
444 }
445
446 return result;
447}
448
449void DepTripletLogger::getCompoundsHeads(
450 VxToTermsMap& result,
451 const BoWTerm* bt) const
452{
453 if (result.find(bt->getVertex()) == result.end())
454 {
455 result.insert(std::make_pair(bt->getVertex(), std::set<const BoWTerm*>()));
456 }
457 result[bt->getVertex()].insert(dynamic_cast<const BoWTerm*>(bt));
458 std::deque<BoWComplexToken::Part>::const_iterator partsit, partsit_end;
459 partsit = bt->getParts().begin(); partsit_end = bt->getParts().end();
460 for (; partsit!=partsit_end; partsit++)
461 {
462 if ( boost::dynamic_pointer_cast<BoWTerm>((*partsit).get<1>()) != 0)
463 {
464 getCompoundsHeads(result, &*boost::dynamic_pointer_cast<BoWTerm>((*partsit).get<1>()));
465 }
466 }
467}
468
469void DepTripletLogger::collectVertices(
470 std::set<LinguisticGraphVertex>& theSet,
471 const BoWToken* term) const
472{
473// std::cerr << " inserting " << term->getVertex() << std::endl;
474 theSet.insert(term->getVertex());
475 if ( dynamic_cast<const BoWTerm*>(term) != 0)
476 {
477 std::deque<BoWComplexToken::Part>::const_iterator partsit, partsit_end;
478 partsit = dynamic_cast<const BoWTerm*>(term)->getParts().begin();
479 partsit_end = dynamic_cast<const BoWTerm*>(term)->getParts().end();
480 for (; partsit!=partsit_end; partsit++)
481 {
482 collectVertices(theSet, &*(*partsit).get<1>());
483 }
484 }
485}
486
487
488} // closing namespace SyntacticAnalysis
489} // closing namespace LinguisticProcessing
490} // closing namespace Lima
This file is the main header file for the data related to annotation graphs.
#define DEPTRIPLETLOGGER_CLASSID
DependencyGraph::edge_iterator DependencyGraphEdgeIt
boost::property_map< DependencyGraph, edge_deprel_type_t >::const_type CEdgeDepRelTypePropertyMap
boost::adjacency_list< boost::vecS, boost::vecS, boost::bidirectionalS, DepVertexProperties, DepEdgeProperties > DependencyGraph
The dependency graph class.
@ edge_deprel_type
#define LIMA_UNUSED(x)
Definition LimaCommon.h:224
#define LDEBUG
Definition LimaCommon.h:157
#define LERROR
Definition LimaCommon.h:161
boost::property_map< LinguisticGraph, vertex_data_t >::const_type CVertexDataPropertyMap
LinguisticGraph::vertex_descriptor LinguisticGraphVertex
@ vertex_data
LinguisticGraph::out_edge_iterator LinguisticGraphOutEdgeIt
boost::adjacency_list< boost::vecS, boost::vecS, boost::bidirectionalS, LinguisticVertexProperties > LinguisticGraph
Property to identify the chains in the graph.
#define SALOGINIT
Defines a Factory to create Object of type Base.
Data used for the syntactic analyzis of texts.
Holds all data that pass through the ProcessUnits Analysis data are shared pointers,...
std::shared_ptr< AnalysisData > getData(const QString &id)
return AnalysisData by id
void setData(const QString &id, std::shared_ptr< AnalysisData > data)
set an analysisData with the given id.
Holds an annotation graph and gives an API to manipulate it.
std::set< AnnotationGraphVertex > matches(const std::string &first, AnnotationGraphVertex firstVx, const std::string &second) const
Gets the set of vertices matched in the second graph by the given vertex of the first graph.
This is a complex token used to represent a multiword term.
Definition bowTerm.h:36
This class contains the representation of an element of the bag of words.
Definition bowToken.h:46
Holds linguistic data for one language.
const MediaData & mediaData(MediaId media) const
std::deque< std::string > & getListsValueAtKey(const std::string &key)
Manage initialization of InitializableObjects using configuration module and parameters.
const InitializationParameters & getInitializationParameters() const
get Initialization Parameters
A generic process unit to log information in files: contains some common informations such as : outpu...
bool openLogFile(std::ofstream &output, const std::string &sourceFile) const
Parameters retrived in the configuration file:
std::vector< std::pair< boost::shared_ptr< Common::BagOfWords::BoWRelation >, boost::shared_ptr< Common::BagOfWords::BoWToken > > > buildTermFor(const AnnotationGraphVertex &vx, const AnnotationGraphVertex &tgt, const LinguisticGraph &anagraph, const LinguisticGraph &posgraph, const uint64_t offset, const SyntacticAnalysis::SyntacticData *syntacticData, const Common::AnnotationGraphs::AnnotationData *annotationData, std::set< LinguisticGraphVertex > &visited) const
Creates the terms reachable from the given annotation vertex.
std::vector< std::pair< boost::shared_ptr< Common::BagOfWords::BoWRelation >, boost::shared_ptr< Common::BagOfWords::AbstractBoWElement > > > createAbstractBoWElement(const LinguisticGraphVertex v, const LinguisticGraph &anagraph, const LinguisticGraph &posgraph, const uint64_t offsetBegin, const Common::AnnotationGraphs::AnnotationData *annotationData, std::set< LinguisticGraphVertex > &visited, bool keepAnyway=false) const
void init(Common::XMLConfigurationFiles::GroupConfigurationStructure &unitConfiguration, MediaId language)
An AnalysisData containing a LinguisticGraph with a language and an id.
const LinguisticGraphVertex & lastVertex(void) const
Returns the last vertex of the graph.
const LinguisticGraphVertex & firstVertex(void) const
Returns the first vertex of the graph.
void init(Common::XMLConfigurationFiles::GroupConfigurationStructure &unitConfiguration, Manager *manager) override
initialize with parameters from configuration file.
LimaStatusCode process(AnalysisContent &analysis) const override
Process on data in analysisContent.
This class points to a graph, its dependency graph and the structure that holds the maping between th...
LinguisticGraphVertex tokenVertexForDepVertex(const DependencyGraphVertex &v) const
static const MediaticData & single()
const singleton accessor
Definition Singleton.h:51
static void logElapsedTime(const std::string &mess, const std::string &taskCategory=std::string(""))
log the number of microseconds since last UpdateCurrentTime
static void updateCurrentTime(const std::string &taskCategory=std::string(""))
store current time for new elapsed time computation
AnnotationGraph::vertex_descriptor AnnotationGraphVertex
SimpleFactory< MediaProcessUnit, DepTripletLogger > DepTripletLoggerFactory(DEPTRIPLETLOGGER_CLASSID)
std::map< LinguisticGraphVertex, std::set< const Common::BagOfWords::BoWTerm * > > VxToTermsMap
NAUTITIA.
LimaStatusCode
Definition LimaCommon.h:236
@ CANNOT_OPEN_FILE_ERROR
Definition LimaCommon.h:239
@ SUCCESS_ID
Definition LimaCommon.h:237
@ MISSING_DATA
Definition LimaCommon.h:243
STL namespace.
launch exception related to the configuration file parsing