LIMA
Libre Multilingual Analyzer — C++ API
Loading...
Searching...
No Matches
SyntacticAnalysisXmlLogger.cpp
Go to the documentation of this file.
1// Copyright 2002-2019 CEA LIST
2// SPDX-FileCopyrightText: 2022 CEA LIST <gael.de-chalendar@cea.fr>
3//
4// SPDX-License-Identifier: MIT
5
17
27
28#include <iostream>
29#include <fstream>
30
31//using namespace boost;
32using namespace boost::tuples;
33using namespace Lima::Common::Misc;
34using namespace Lima::Common::MediaticData;
36
37typedef boost::color_traits<boost::default_color_type> Color;
38
39namespace Lima
40{
41namespace LinguisticProcessing
42{
43namespace SyntacticAnalysis
44{
45
47
51
52
55
58 Manager* manager)
59
60{
61 AbstractTextualAnalysisDumper::init(unitConfiguration,manager);
62
63 m_language=manager->getInitializationParameters().media;
64 m_propertyCodeManager= &(static_cast<const Common::MediaticData::LanguageData&>(Common::MediaticData::MediaticData::single().mediaData(m_language)).getPropertyCodeManager());
65}
66
68 AnalysisContent& analysis) const
69{
71
72 auto metadata = std::dynamic_pointer_cast<LinguisticMetaData>(analysis.getData("LinguisticMetaData"));
73 if (metadata == 0) {
75 LERROR << "no LinguisticMetaData ! abort";
76 return MISSING_DATA;
77 }
78
79 auto dstream = initialize(analysis);
80 std::ostream& outputStream=dstream->out();
81 /*std::ofstream outputStream;
82 if (!openLogFile(outputStream,metadata->getMetaData("FileName")))
83 {
84 SALOGINIT;
85 LERROR << "Can't open log file ";
86 return CANNOT_OPEN_FILE_ERROR;
87 }*/
88
90
91 auto syntacticData = std::dynamic_pointer_cast<const SyntacticData>(analysis.getData("SyntacticData"));
92 if (syntacticData==0)
93 {
94 LERROR << "no SyntacticData ! abort";
95 return MISSING_DATA;
96 }
97
98 auto anagraph = std::dynamic_pointer_cast<AnalysisGraph>(analysis.getData("PosGraph"));
99 if (anagraph==0)
100 {
101 LERROR << "no AnalysisGraph ! abort";
102 return MISSING_DATA;
103 }
104 auto sb = std::dynamic_pointer_cast<SegmentationData>(analysis.getData("SentenceBoundaries"));
105 if (sb==0)
106 {
107 LERROR << "no SentenceBounds ! abort";
108 return MISSING_DATA;
109 }
110// LinguisticGraph* graph=anagraph->getGraph();
111
112 std::set< std::pair<size_t, size_t> > alreadyDumped;
113
114 outputStream << "<?xml version='1.0' encoding='UTF-8'?>" << std::endl;
115 outputStream << "<syntactic_analysis_dump>" << std::endl;
116
117
118 // ??OME2 SegmentationData::iterator sbItr=sb->begin();
119 std::vector<Segment>::iterator sbItr=(sb->getSegments()).begin();
120
121 while (sbItr!=(sb->getSegments()).end())
122 {
123 LinguisticGraphVertex beginSentence=sbItr->getFirstVertex();
124 LinguisticGraphVertex endSentence=sbItr->getLastVertex();
125
126 dumpLimaData(outputStream,
127 beginSentence,
128 endSentence,
129 anagraph.get(),
130 syntacticData.get());
131
132 sbItr++;
133 }
134
135 outputStream << "</syntactic_analysis_dump>" << std::endl;
136
137 TimeUtils::logElapsedTime("SyntacticAnalysisXmlLogger");
138 return SUCCESS_ID;
139}
140
141
142//***********************************************************************
143// main function for outputing the graph
144//***********************************************************************
145void SyntacticAnalysisXmlLogger::dumpLimaData(std::ostream& os,
146 const LinguisticGraphVertex begin,
147 const LinguisticGraphVertex end,
148 const AnalysisGraph* anagraph,
149 const SyntacticData* syntacticData,
150 const uint64_t offsetBegin) const
151{
152 std::vector< bool > alreadyDumpedTokens;
153 std::map< LinguisticAnalysisStructure::Token*, uint64_t > tokens;
154
155 LinguisticGraph* graph = const_cast< LinguisticGraph* >(anagraph->getGraph());
156 // go through the graph, add BoWTokens that are not in complex terms
157 DumpGraphVisitor vis(*this, os,end, syntacticData,
158 tokens, alreadyDumpedTokens,
159 m_language,offsetBegin);
160
161 os << "<sentence>" << std::endl;
162 try
163 {
164 //breadth_first_search(*graph, begin, visitor(vis));
165 // I dont know why the direct call to breadth_first_search does
166 // not work (bug when trying to go between vertices 0 and 1; because
167 // of the 0->1 edge) :
168 // initializing the colors and calling breadth_first_visit
169 // works (?)
171 uint64_t id = 0;
172 alreadyDumpedTokens.resize(num_vertices(*graph));
173 for (boost::tie(i, i_end) = vertices(*graph); i != i_end; ++i)
174 {
175 put(boost::vertex_color, *graph, *i, Color::white());
176 alreadyDumpedTokens[id] = false;
177 tokens[get(vertex_token, *graph, *i)] = id;
178 id++;
179 }
180 boost::breadth_first_visit(*graph, begin, boost::visitor(vis));
181 }
182 catch (DumpGraphVisitor::EndOfSearch&)
183 { //do nothing: normal ending
184 }
185 os << "</sentence>" << std::endl;
186}
187
188//***********************************************************************
189// output functions
190//***********************************************************************
191
192
193LimaString SyntacticAnalysisXmlLogger::getPosition(
194 const uint64_t position,
195 const uint64_t offsetBegin)
196{
197 return QString::number(offsetBegin+position);
198}
199
200void SyntacticAnalysisXmlLogger::outputVertex(const LinguisticGraphVertex v,
201 const LinguisticGraph& graph,
202 const uint64_t offsetBegin,
203 const SyntacticData* syntacticData,
204 std::ostream& xmlStream,
205 std::map< LinguisticAnalysisStructure::Token*, uint64_t >& tokens,
206 std::vector< bool >& alreadyDumpedTokens) const
207{
208 if (v == syntacticData->iterator()->firstVertex() ||
209 v == syntacticData->iterator()->lastVertex())
210 {
211 xmlStream << "<vertex id=\"" << v << "\" />" << std::endl;
212 return;
213 }
214 auto token = get(vertex_token, graph, v);
215
216 auto tokenId = (*(tokens.find(token))).second;
217// bool alreadyDumped = alreadyDumpedTokens[tokenId];
218
219 xmlStream << "<vertex id=\"" << v << "\" form=\""
220 << token->stringForm().toStdString() << "\" pos=\""
221 << getPosition(token->position(), offsetBegin).toStdString()
222 << "\" ";
223 const auto& chains = get(vertex_chain_id, graph,v);
224 xmlStream << " >" << std::endl;
225 if (chains.size() > 0)
226 {
227 xmlStream << "<chains>" << std::endl;
228 auto itChains = chains.cbegin(); auto itChains_end = chains.cend();
229 for (; itChains != itChains_end; itChains++)
230 {
231 const auto& ids = (*itChains);
232 xmlStream << "<chain type=\"";
233 if (ids.chainType() == Common::MediaticData::NO_CHAIN_TYPE)
234 xmlStream << "0";
235 else if (ids.chainType() == Common::MediaticData::NOMINAL)
236 xmlStream << "N";
237 else
238 xmlStream << "V";
239 xmlStream << "\" id=\"" << (ids.chainId()) << "\" />" << std::endl;
240 }
241 xmlStream << "</chains>" << std::endl;
242 }
243
244 const auto depGraph = syntacticData->dependencyGraph();
245 auto depV = syntacticData->depVertexForTokenVertex(v);
246 if (out_degree(depV, *depGraph) > 0)
247 {
248
249 xmlStream << "<dependents>" << std::endl;
250 DependencyGraphOutEdgeIt depIt, depIt_end;
251 boost::tie(depIt, depIt_end) = out_edges(depV, *depGraph);
252 for (; depIt != depIt_end; depIt++)
253 {
254 auto depTargV = target(*depIt, *depGraph);
255 auto targV = syntacticData-> tokenVertexForDepVertex(depTargV);
256// CEdgeDepChainIdPropertyMap chainsMap = get(edge_depchain_id, *depGraph);
257 CEdgeDepRelTypePropertyMap relTypeMap = get(edge_deprel_type, *depGraph);
258 xmlStream << "<dep v=\"" << targV;
259// xmlStream << "\" c=\"" << chainsMap[*depIt];
260 auto relName = static_cast<const Common::MediaticData::LanguageData&>(
261 Common::MediaticData::MediaticData::single().mediaData(m_language)).getSyntacticRelationName(
262 relTypeMap[*depIt]);
263 if (relName.empty())
264 {
265 relName="UNKNOWN";
266 }
267 xmlStream << "\" t=\"" << relName << "\" />" << std::endl;
268 }
269 xmlStream << "</dependents>" << std::endl;
270 }
271
272 const auto& sp = Common::MediaticData::MediaticData::single().stringsPool(m_language);
273
274 auto word = get(vertex_data, graph, v);
275 word->outputXml(xmlStream, *m_propertyCodeManager, sp);
276 xmlStream << "<ref>" << tokenId << "</ref>" << std::endl;
277 alreadyDumpedTokens[tokenId] = true;
278 xmlStream << "</vertex>" << std::endl;
279
280}
281
282void SyntacticAnalysisXmlLogger::outputEdge(const LinguisticGraphEdge e,
283 const LinguisticGraph& graph,
284 std::ostream& xmlStream) const
285{
286 xmlStream << " <edge src=\"" << source(e, graph)
287 << "\" targ=\"" << target(e, graph) << "\" />" << std::endl;
288}
289
290
291//***********************************************************************
292// visitor definition
293//***********************************************************************
294// examine_vertex to test if we are at end of search
295void SyntacticAnalysisXmlLogger::DumpGraphVisitor::examine_vertex(LinguisticGraphVertex v,
296 const LinguisticGraph& g)
297{
298// DUMPERLOGINIT;
299// LDEBUG << "DumpGraphVisitor: examine_vertex " << v;
300
301 if (v == m_lastVertex)
302 {
303 bool finished = true;
304 LinguisticGraphInEdgeIt it, it_end;
305 boost::tie(it, it_end) = in_edges(v, g);
306 while (finished && (it != it_end))
307 {
308 if (get(boost::vertex_color, g,source(*it, g)) != Color::black())
309 {
310 finished = false;
311 }
312 it++;
313 }
314 if (finished)
315 {
316// LDEBUG << "DumpGraphVisitor: finished";
317 throw EndOfSearch();
318 }
319 }
320}
321
322void SyntacticAnalysisXmlLogger::DumpGraphVisitor::examine_edge(LinguisticGraphEdge e,
323 const LinguisticGraph& g)
324{
325// DUMPERLOGINIT;
326// LDEBUG << "DumpGraphVisitor: discover_edge " << e;
327
328 m_dumper.outputEdge(e, g, m_os);
329}
330
331void SyntacticAnalysisXmlLogger::DumpGraphVisitor::discover_vertex(LinguisticGraphVertex v,
332 const LinguisticGraph& graph)
333{
334 m_dumper.outputVertex(v, graph, m_offsetBegin, m_syntacticData,
335 m_os, m_tokens, m_alreadyDumpedTokens);
336}
337
338
339
340} // SyntacticAnalysis
341} // LinguisticProcessing
342} // Lima
DependencyGraph::out_edge_iterator DependencyGraphOutEdgeIt
boost::property_map< DependencyGraph, edge_deprel_type_t >::const_type CEdgeDepRelTypePropertyMap
@ edge_deprel_type
#define LERROR
Definition LimaCommon.h:161
LinguisticGraph::in_edge_iterator LinguisticGraphInEdgeIt
boost::graph_traits< LinguisticGraph >::edge_descriptor LinguisticGraphEdge
typedefs to simplify the access to various graphs elements
LinguisticGraph::vertex_iterator LinguisticGraphVertexIt
@ vertex_token
LinguisticGraph::vertex_descriptor LinguisticGraphVertex
@ vertex_data
boost::adjacency_list< boost::vecS, boost::vecS, boost::bidirectionalS, LinguisticVertexProperties > LinguisticGraph
Property to identify the chains in the graph.
@ vertex_chain_id
#define SALOGINIT
Defines a Factory to create Object of type Base.
boost::color_traits< boost::default_color_type > Color
Debug logger for dependency graphs.
#define SYNTACTICANALYSISXMLLOGGER_CLASSID
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
Holds linguistic data for one language.
const FsaStringsPool & stringsPool(MediaId med) const
const MediaData & mediaData(MediaId media) const
Manage initialization of InitializableObjects using configuration module and parameters.
const InitializationParameters & getInitializationParameters() const
get Initialization Parameters
std::shared_ptr< DumperStream > initialize(AnalysisContent &analysis) const
virtual void init(Common::XMLConfigurationFiles::GroupConfigurationStructure &unitConfiguration, Manager *manager) override
initialize with parameters from configuration file.
An AnalysisData containing a LinguisticGraph with a language and an id.
const LinguisticGraphVertex & lastVertex(void) const
Returns the last vertex of the graph.
const LinguisticGraph * getGraph(void) const
Returns the underlying graph structure.
const LinguisticGraphVertex & firstVertex(void) const
Returns the first vertex of the graph.
virtual LimaStatusCode process(AnalysisContent &analysis) const override
Do the job of logging the dependency graph of the given text analysis.
virtual void init(Common::XMLConfigurationFiles::GroupConfigurationStructure &unitConfiguration, Manager *manager) override
MediaProcessUnit initialization method.
This class points to a graph, its dependency graph and the structure that holds the maping between th...
DependencyGraphVertex depVertexForTokenVertex(const LinguisticGraphVertex &v) const
LinguisticAnalysisStructure::AnalysisGraph * iterator()
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
SimpleFactory< MediaProcessUnit, SyntacticAnalysisXmlLogger > syntacticAnalysisXmlLoggerFactory(SYNTACTICANALYSISXMLLOGGER_CLASSID)
NAUTITIA.
LimaStatusCode
Definition LimaCommon.h:236
@ SUCCESS_ID
Definition LimaCommon.h:237
@ MISSING_DATA
Definition LimaCommon.h:243
QString LimaString
Definition LimaString.h:33