LIMA
Libre Multilingual Analyzer — C++ API
Loading...
Searching...
No Matches
TemporalSegmentationFeatures.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 *
8 * @file TemporalSegmentationFeatures.cpp
9 * @author Romaric Besancon (romaric.besancon@cea.fr)
10 * @date Thu Feb 10 2011
11 * copyright Copyright (C) 2011 by CEA LIST
12 *
13 ***********************************************************************/
14
18#include <sstream>
19#include <queue>
20
21using namespace std;
22using namespace boost;
24using namespace Lima::Common::AnnotationGraphs;
25
26namespace Lima {
27namespace LinguisticProcessing {
28
29//***********************************************************************
30// factories
36
37//***********************************************************************
38// feature accessors
39//***********************************************************************
40SegmentFeatureEntity::SegmentFeatureEntity(MediaId language, const std::string& complement):
41AbstractSegmentFeatureExtractor(language,complement),
42m_entityName(complement),
43m_entityType(),
44m_annotationData(0)
45{
47 getEntityType(Common::Misc::utf8stdstring2limastring(complement));
48}
49
51update(const AnalysisContent& analysis) {
52 m_annotationData = static_cast<const AnnotationData*>(analysis.getData("AnnotationData"));
53 if (m_annotationData==0)
54 {
55 LOGINIT("LP::Segmentation");
56 LERROR << "no annotation graph available !";
57 }
58}
59
61getValue(const AnalysisGraph* anagraph,
62 const Segment& seg) const
63{
64 uint64_t nbEntities(0);
65 if (m_annotationData!=0) {
66
67 bool isPosGraph=(anagraph->getGraphId()=="PosGraph");
68
69 // check if an entity of a given type exists in the segment :
70 // go through the graph inside the segment
71 const LinguisticGraph* graph=anagraph->getGraph();
72 LinguisticGraphVertex lastVertex=anagraph->lastVertex();
73
74 std::queue<LinguisticGraphVertex> toVisit;
75 std::set<LinguisticGraphVertex> visited;
76
77 LinguisticGraphOutEdgeIt outItr,outItrEnd;
78
79 toVisit.push(seg.getFirstVertex());
80
81 bool first=true;
82 bool last=false;
83 while (!toVisit.empty()) {
84 LinguisticGraphVertex v=toVisit.front();
85 toVisit.pop();
86 if (last || v == lastVertex) {
87 continue;
88 }
89 if (v == seg.getLastVertex()) {
90 last=true;
91 }
92
93 for (boost::tie(outItr,outItrEnd)=out_edges(v,*graph); outItr!=outItrEnd; outItr++)
94 {
95 LinguisticGraphVertex next=target(*outItr,*graph);
96 if (visited.find(next)==visited.end())
97 {
98 visited.insert(next);
99 toVisit.push(next);
100 }
101 }
102
103 if (first) {
104 first=false;
105 }
106 else {
107 // check for entity
108 if (isPosGraph) {
109 if (isVertexInPosGraphAnEntityOfType(v, m_annotationData, m_entityType)) {
110 nbEntities++;
111 }
112 else {
113 if (isAnEntityOfType(v, m_annotationData, m_entityType, "AnalysisGraph")) {
114 nbEntities++;
115 }
116 }
117 }
118 }
119 }
120 }
121 ostringstream oss;
122 oss << m_entityName << "_" << nbEntities;
123 return oss.str();
124}
125
126bool SegmentFeatureEntity::
127isAnEntityOfType(LinguisticGraphVertex v,
128 const Common::AnnotationGraphs::AnnotationData* annotationData,
130 const std::string& graphId) const
131{
132 std::set< AnnotationGraphVertex > matches = annotationData->matches(graphId,v,"annot");
133 for (std::set< AnnotationGraphVertex >::const_iterator it = matches.begin();
134 it != matches.end(); it++)
135 {
137 if (annotationData->hasAnnotation(vx, Common::Misc::utf8stdstring2limastring("SpecificEntity")))
138 {
140 annotationData->annotation(vx, Common::Misc::utf8stdstring2limastring("SpecificEntity")).
141 pointerValue<SpecificEntities::SpecificEntityAnnotation>();
142 if (se->getType()==type) {
143 return true;
144 }
145 }
146 }
147 return false;
148}
149
150
151bool SegmentFeatureEntity::
152isVertexInPosGraphAnEntityOfType(LinguisticGraphVertex v,
153 const Common::AnnotationGraphs::AnnotationData* annotationData,
155{
156
157 // first, check if vertex corresponds to a specific entity found before pos tagging (i.e. in analysis graph)
158 std::set< AnnotationGraphVertex > anaVertices = annotationData->matches("PosGraph",v,"AnalysisGraph");
159 // note: anaVertices size should be 0 or 1
160 for (std::set< AnnotationGraphVertex >::const_iterator anaVerticesIt = anaVertices.begin();
161 anaVerticesIt != anaVertices.end(); anaVerticesIt++)
162 {
163 if (isAnEntityOfType(*anaVerticesIt,annotationData,type,"AnalysisGraph")) {
164 return true;
165 }
166 }
167
168 // check annotations directly in PosGraph
169 if (isAnEntityOfType(v,annotationData,type,"PosGraph")) {
170 return true;
171 }
172
173 return false;
174}
175
176//***********************************************************************
177SegmentFeatureEntityInData::SegmentFeatureEntityInData(MediaId language, const std::string& complement):
178AbstractSegmentFeatureExtractor(language,complement),
179m_entityName(),
180m_dataName(),
181m_entityType()
182{
183 // complement contains the name of the entity + the name of the data
184 // in which it is stored (separated by a comma)
185 string::size_type i=complement.find(",");
186 if (i==string::npos) {
187 LOGINIT("LP::Segmentation");
188 LERROR << "No data name provided for entityInData";
189 m_entityName=complement;
190 }
191 else {
192 m_entityName=string(complement,0,i);
193 m_dataName=string(complement,i+1);
194 }
196 getEntityType(Common::Misc::utf8stdstring2limastring(m_entityName));
197}
198
200update(const AnalysisContent& analysis) {
201
202 // get result data
203 const AnalysisData* resultData=analysis.getData(m_dataName);
204 if (resultData == 0) {
205 LOGINIT("LP::Segmentation");
206 LERROR << "no data " << m_data << "in AnalysisContent";
207 }
208 m_data=dynamic_cast<const ApplyRecognizer::RecognizerResultData*>(resultData);
209 if (m_data == 0) {
210 LOGINIT("LP::Segmentation");
211 LERROR << "data " << m_data << "in AnalysisContent is not a RecognizerResultData";
212 }
213
214}
215
217getValue(const AnalysisGraph* /*anagraph*/,
218 const Segment& seg) const
219{
220 if (m_data==0) {
221 return "";
222 }
223 uint64_t nbEntities(0);
224 for (ApplyRecognizer::RecognizerResultData::const_iterator it=m_data->begin(),it_end=m_data->end();
225 it!=it_end; it++) {
226 for (std::vector< Automaton::RecognizerMatch >::const_iterator m=(*it).begin(),
227 m_end=(*it).end(); m!=m_end; m++) {
228 if ((*m).getType()==m_entityType &&
229 (*m).positionBegin()>=seg.getPosBegin() &&
230 (*m).positionEnd()<=seg.getPosEnd()) {
231 nbEntities++;
232 }
233 }
234 }
235 ostringstream oss;
236 oss << m_entityName << "_" << nbEntities;
237 return oss.str();
238}
239
240//***********************************************************************
241SegmentFeatureRank::SegmentFeatureRank(MediaId language, const std::string& complement):
242AbstractSegmentFeatureExtractor(language,complement),
243m_data(),
244m_segmData(0)
245{
246 m_data=complement;
247}
248
250update(const AnalysisContent& analysis) {
251 // store information from segmentation data to know at which segment we are
252 const AnalysisData* data=analysis.getData(m_data);
253 if (data==0) {
254 return;
255 }
256 m_segmData=static_cast<const SegmentationData*>(data);
257}
258
260getValue(const AnalysisGraph* /*graph*/,
261 const Segment& seg) const
262{
263 // give rank of segment in segmentation data
264 uint64_t rank(0);
265 uint64_t i(0);
266 for (vector<Segment>::const_iterator it=m_segmData->getSegments().begin(),
267 it_end=m_segmData->getSegments().end();it!=it_end;it++) {
268 if ((*it).getPosBegin()==seg.getPosBegin() && (*it).getLength() == seg.getLength()) {
269 rank=i;
270 break;
271 }
272 i++;
273 }
274 ostringstream oss;
275 oss << "rank_" << rank;
276 return oss.str();
277}
278
279//***********************************************************************
280SegmentFeatureCheckProperty::SegmentFeatureCheckProperty(MediaId language, const std::string& complement):
281AbstractSegmentFeatureExtractor(language,complement),
282m_propertyName(""),
283m_propertyValue(""),
284m_value(0),
285m_propertyAccessor(0)
286{
287 string::size_type i=complement.find("=");
288 if (i==string::npos) {
289 LOGINIT("LP::Segmentation");
290 LERROR << SegmentFeatureCheckProperty_ID << ": no property value (format must be PROPERTY=VALUE)";
291 }
292 else {
293 m_propertyName=string(complement,0,i);
294 m_propertyValue=string(complement,i+1);
297 m_propertyAccessor=&codeManager.getPropertyAccessor(m_propertyName);
298
299 const Common::PropertyCode::PropertyManager* propertyManager=&codeManager.getPropertyManager(m_propertyName);
300
301 m_value=propertyManager->getPropertyValue(m_propertyValue);
302 }
303}
304
307
309getValue(const AnalysisGraph* anagraph,
310 const Segment& seg) const
311{
312 // check if initialization has been successful
313 if (m_propertyAccessor==0) {
314 return "";
315 }
316
317 uint64_t nbProp(0);
318
319 // go through the graph inside the segment
320 const LinguisticGraph* graph=anagraph->getGraph();
321 LinguisticGraphVertex lastVertex=anagraph->lastVertex();
322
323 std::queue<LinguisticGraphVertex> toVisit;
324 std::set<LinguisticGraphVertex> visited;
325
326 LinguisticGraphOutEdgeIt outItr,outItrEnd;
327
328 toVisit.push(seg.getFirstVertex());
329
330 bool first=true;
331 bool last=false;
332 while (!toVisit.empty()) {
333 LinguisticGraphVertex v=toVisit.front();
334 toVisit.pop();
335 if (last || v == lastVertex) {
336 continue;
337 }
338 if (v == seg.getLastVertex()) {
339 last=true;
340 }
341
342 for (boost::tie(outItr,outItrEnd)=out_edges(v,*graph); outItr!=outItrEnd; outItr++)
343 {
344 LinguisticGraphVertex next=target(*outItr,*graph);
345 if (visited.find(next)==visited.end())
346 {
347 visited.insert(next);
348 toVisit.push(next);
349 }
350 }
351
352 if (first) {
353 first=false;
354 }
355 else {
356 // check for entity
357 if (isProperty(v, graph, m_value)) {
358 nbProp++;
359 }
360 }
361 }
362
363 ostringstream oss;
364 oss << m_propertyValue << "_" << nbProp;
365 return oss.str();
366}
367
368bool SegmentFeatureCheckProperty::
369isProperty(LinguisticGraphVertex v,
370 const LinguisticGraph* graph,
371 LinguisticCode propertyValue) const
372{
373 const MorphoSyntacticData* data=get(vertex_data,*graph,v);
374 for (MorphoSyntacticData::const_iterator m=data->begin(),m_end=data->end();m!=m_end;m++)
375 {
376 LinguisticCode code=m_propertyAccessor->readValue((*m).properties);
377 if (code==propertyValue) {
378 return true;
379 }
380 }
381 return false;
382}
383
384//***********************************************************************
385SegmentFeatureInSegment::SegmentFeatureInSegment(MediaId language, const std::string& complement):
386AbstractSegmentFeatureExtractor(language,complement),
387m_segmentData(""),
388m_data(0)
389{
390 m_segmentData=complement;
391}
392
394update(const AnalysisContent& analysis)
395{
396 const AnalysisData* data=analysis.getData(m_segmentData);
397 if (data==0) {
398 LOGINIT("LP::Segmentation");
399 LERROR << SegmentFeatureInSegment_ID << ": No data " << m_segmentData;
400 m_data=0;
401 }
402 else {
403 m_data=static_cast<const SegmentationData*>(data);
404 }
405}
406
408getValue(const AnalysisGraph* /*anagraph*/,
409 const Segment& seg) const
410{
411 if (m_data==0) {
412 return "";
413 }
414 std::string segmentType;
415 //find corresponding segment in given segmentation data
416 // ??OME2 for (SegmentationData::const_iterator s=m_data->begin(),s_end=m_data->end();s!=s_end;s++)
417 for (std::vector<Segment>::const_iterator s=(m_data->getSegments()).begin(),s_end=(m_data->getSegments()).end();s!=s_end;s++)
418 {
419 if ((*s).getPosBegin() <= seg.getPosBegin() && (*s).getPosEnd() >= seg.getPosEnd()) {
420 segmentType=(*s).getType();
421 break;
422 }
423 }
424 if (segmentType.empty()) {
425 return "";
426 }
427 ostringstream oss;
428 oss << segmentType << "_1";
429 return oss.str();
430}
431
432} // end namespace
433} // end namespace
#define LOGINIT(X)
Definition LimaCommon.h:187
#define LERROR
Definition LimaCommon.h:161
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 SegmentFeatureRank_ID
#define SegmentFeatureEntity_ID
#define SegmentFeatureCheckProperty_ID
#define SegmentFeatureInSegment_ID
#define SegmentFeatureEntityInData_ID
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
just for semantics: base class for analysisData
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.
const GenericAnnotation & annotation(AnnotationGraphVertex v1, AnnotationGraphVertex v2, const LimaString &annot) const
Holds linguistic data for one language.
const MediaData & mediaData(MediaId media) const
LinguisticCode readValue(const LinguisticCode &code) const
read a property in a coded int.
Provide tools to parse a property file, and deal with the property coding system.
const PropertyManager & getPropertyManager(const std::string &propertyName) const
Get the PropertyManager associated to a property.
const PropertyAccessor & getPropertyAccessor(const std::string &propertyName) const
Get the PropertyAccessor associated to a property.
Provide tools to manage a specific property.
LinguisticCode getPropertyValue(const std::string &symbolicValue) const
Get the coded property value from the symbolic value.
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.
std::string getValue(const LinguisticAnalysisStructure::AnalysisGraph *graph, const Segment &seg) const
SegmentFeatureCheckProperty(MediaId language, const std::string &complement="")
SegmentFeatureEntityInData(MediaId language, const std::string &complement="")
std::string getValue(const LinguisticAnalysisStructure::AnalysisGraph *graph, const Segment &seg) const
std::string getValue(const LinguisticAnalysisStructure::AnalysisGraph *graph, const Segment &seg) const
SegmentFeatureEntity(MediaId language, const std::string &complement="")
std::string getValue(const LinguisticAnalysisStructure::AnalysisGraph *graph, const Segment &seg) const
SegmentFeatureInSegment(MediaId language, const std::string &complement="")
std::string getValue(const LinguisticAnalysisStructure::AnalysisGraph *graph, const Segment &seg) const
SegmentFeatureRank(MediaId language, const std::string &complement="")
LinguisticGraphVertex getFirstVertex() const
LinguisticGraphVertex getLastVertex() const
const std::vector< Segment > & getSegments() const
A representation of a specific entity to store in the annotation graph.
static const MediaticData & single()
const singleton accessor
Definition Singleton.h:51
AnnotationGraph::vertex_descriptor AnnotationGraphVertex
bool hasAnnotation(AnnotationGraphVertex v, const LimaString &annot) const
LimaString utf8stdstring2limastring(const std::string &src)
SegmentFeatureExtractorFactory< SegmentFeatureEntity > SegmentFeatureEntityFactory(SegmentFeatureEntity_ID)
SegmentFeatureExtractorFactory< SegmentFeatureRank > SegmentFeatureRankFactory(SegmentFeatureRank_ID)
SegmentFeatureExtractorFactory< SegmentFeatureCheckProperty > SegmentFeatureCheckPropertyFactory(SegmentFeatureCheckProperty_ID)
SegmentFeatureExtractorFactory< SegmentFeatureInSegment > SegmentFeatureInSegmentFactory(SegmentFeatureInSegment_ID)
SegmentFeatureExtractorFactory< SegmentFeatureEntityInData > SegmentFeatureEntityInDataFactory(SegmentFeatureEntityInData_ID)
NAUTITIA.
STL namespace.