LIMA
Libre Multilingual Analyzer — C++ API
Loading...
Searching...
No Matches
SentenceBoundariesUpdater.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
7
13#include "SegmentationData.h"
15
16#include <string>
17
18using namespace std;
20using namespace Lima::Common;
21
22namespace Lima
23{
24namespace LinguisticProcessing
25{
26namespace TextSegmentation
27{
29{
30
31#define DEBUG_THIS_FILE true
32#define LOG_ERROR_AND_THROW(msg, exc) { \
33 SENTENCEBOUNDARIESUPDATERLOGINIT; \
34 LERROR << msg; \
35 throw exc; \
36 }
37
38#define LOG_ERROR_AND_EXIT(msg, err_code) { \
39 SENTENCEBOUNDARIESUPDATERLOGINIT; \
40 LERROR << msg; \
41 return err_code; \
42 }
43
44namespace
45{
46inline string THIS_FILE_LOGGING_CATEGORY()
47{
49 return logger.zone().toStdString();
50}
51}
52
53#if defined(DEBUG_LP) && defined(DEBUG_THIS_FILE)
54 #define LOG_MESSAGE(stream, msg) { stream << msg; }
55 #define LOG_MESSAGE_WITH_PROLOG(stream, msg) SENTENCEBOUNDARIESUPDATERLOGINIT; LOG_MESSAGE(stream, msg);
56#else
57 #define LOG_MESSAGE(stream, msg) ;
58 #define LOG_MESSAGE_WITH_PROLOG(stream, msg) ;
59#endif
60
62
64{
65public:
68
70 LimaStatusCode process(AnalysisContent& analysis) const;
71
72private:
73 size_t updateBoundaries(SegmentationData& sb, const AnalysisGraph& graph) const;
74
75 string m_graphName;
76 string m_sbLayerName;
77};
78
80 : ConfigurationHelper("SentenceBoundariesUpdater", THIS_FILE_LOGGING_CATEGORY())
81{
82}
83
87
91
96
99 Manager* manager)
100{
101 LIMA_UNUSED(manager);
102 m_d->init(unitConfiguration);
103}
104
106{
107 TimeUtilsController SentenceBoundariesUpdaterProcessTime("SentenceBoundariesUpdater");
108
109 LimaStatusCode code = m_d->process(analysis);
110
111 TimeUtils::logElapsedTime("SentenceBoundariesUpdater::process");
112
113 return code;
114}
115
121
123{
124 auto graph = std::dynamic_pointer_cast<AnalysisGraph>(analysis.getData(m_graphName));
125 if (graph == nullptr)
126 {
127 LOG_ERROR_AND_EXIT("SentenceBoundariesUpdaterPrivate::process graph" << m_graphName << "has not been produced: check pipeline",
129 }
130
131 auto sb = std::dynamic_pointer_cast<SegmentationData>(analysis.getData(m_sbLayerName));
132 if (sb == nullptr)
133 {
134 LOG_ERROR_AND_EXIT("SentenceBoundariesUpdaterPrivate::process segmentation data" << m_sbLayerName << "has not been produced: check pipeline",
136 }
137
138 updateBoundaries(*sb, *graph);
139
140 return SUCCESS_ID;
141}
142
143size_t SentenceBoundariesUpdaterPrivate::updateBoundaries(SegmentationData& sb, const AnalysisGraph& graph) const
144{
146 size_t segmentsMerged = 0;
147 vector<Segment>& segments = sb.getSegments();
148 map<LinguisticGraphVertex, vector<Segment>::iterator> lastVerticies;
149
150 for (auto it = segments.begin(); it != segments.end(); it++)
151 {
152 LinguisticGraphVertex v = it->getLastVertex();
153 if (lastVerticies.end() != lastVerticies.find(v))
154 {
155 LOG_ERROR_AND_EXIT("SentenceBoundariesUpdaterPrivate::updateBoundaries: vertex" << v << "mentioned twice as segment's end",
157 }
158 lastVerticies[v] = it;
159 }
160
161 list<pair<vector<Segment>::iterator, vector<Segment>::iterator>> segments_to_merge;
162 for (auto it = segments.begin(); it != segments.end(); it++)
163 {
164 set<LinguisticGraphVertex> visited;
165 list<LinguisticGraphVertex> toVisit;
166 toVisit.push_back(it->getFirstVertex());
167
168 while (!toVisit.empty())
169 {
170 LinguisticGraphVertex currentVertex = toVisit.front();
171 toVisit.pop_front();
172 visited.insert(currentVertex);
173
174 auto iter = lastVerticies.find(currentVertex);
175 if (lastVerticies.end() != iter)
176 {
177 if (iter->second > it)
178 {
179 // This is the end of one of following segments
180 segments_to_merge.push_back(make_pair(it, iter->second));
181 it = iter->second;
182 break;
183 }
184 else if (iter->second == it)
185 {
186 break;
187 }
188 }
189
190 for ( LinguisticGraphVertex next : getFollowingNodes<SetOfLinguisticGraphVertices>(graph, currentVertex) )
191 {
192 if (visited.end() == visited.find(next))
193 {
194 toVisit.push_back(next);
195 }
196 }
197 }
198 }
199
200 segments_to_merge.reverse();
201 for (const pair<vector<Segment>::iterator, vector<Segment>::iterator>& p : segments_to_merge)
202 {
203 segmentsMerged += p.second - p.first;
204
205 // Update FirstVertex
206 p.second->setFirstVertex(p.first->getFirstVertex());
207 uint64_t c = 0;
208 for (vector<Segment>::iterator i = p.first; i != p.second; i++)
209 {
210 c += i->getLength();
211 }
212
213 // Update Length
214 p.second->setLength(p.second->getLength() + c);
215
216 // Erase vertices starting from p.first until p.second (p.second is not erased)
217 segments.erase(p.first, p.second);
218 }
219
220 LDEBUG << "segmentsMerged==" << segmentsMerged;
221 return segmentsMerged;
222}
223
224} // namespace SentenceBoundariesUpdater
225} // namespace TextSegmentation
226} // namespace LinguisticProcessing
227} // namespace Lima
#define LIMA_UNUSED(x)
Definition LimaCommon.h:224
#define LDEBUG
Definition LimaCommon.h:157
std::set< LinguisticGraphVertex > SetOfLinguisticGraphVertices
LinguisticGraph::vertex_descriptor LinguisticGraphVertex
#define SENTENCEBOUNDARIESUPDATERLOGINIT
#define LOG_ERROR_AND_EXIT(msg, err_code)
#define SENTENCEBOUNDARIESUPDATER_CLASSID
Defines a Factory to create Object of type Base.
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
Manage initialization of InitializableObjects using configuration module and parameters.
void getStringParameter(Common::XMLConfigurationFiles::GroupConfigurationStructure &unitConfiguration, const std::string &name, std::string &value, int flags=Flags::REQUIRED, std::string default_value="")
An AnalysisData containing a LinguisticGraph with a language and an id.
const std::vector< Segment > & getSegments() const
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 file contains a class to control log of informations about time, such as logging cumulated time ...
static void logElapsedTime(const std::string &mess, const std::string &taskCategory=std::string(""))
log the number of microseconds since last UpdateCurrentTime
void getFollowingNodes(const LinguisticAnalysisStructure::AnalysisGraph &graph, const LinguisticGraphVertex v, T &output_container)
static SimpleFactory< MediaProcessUnit, SentenceBoundariesUpdater > sentenceboundariesupdaterFactory(SENTENCEBOUNDARIESUPDATER_CLASSID)
NAUTITIA.
LimaStatusCode
Definition LimaCommon.h:236
@ UNKNOWN_ERROR
Definition LimaCommon.h:238
@ SUCCESS_ID
Definition LimaCommon.h:237
@ MISSING_DATA
Definition LimaCommon.h:243
STL namespace.