33namespace LinguisticProcessing {
34namespace EventAnalysis {
41m_templateDefinition(0),
43m_maxCharCompatibleEvents(200),
44m_useSentenceBounds(false),
45m_sentenceBoundsData(
"SentenceBoundaries")
64 m_templateDefinition = std::dynamic_pointer_cast<EventTemplateDefinitionResource>(res);
69 LERROR <<
"TemplateMerging: Missing 'eventTemplate' parameter in EventTemplateMerging definition";
72 catch (std::exception& e) {
74 LERROR <<
"TemplateMerging: Missing ressource for 'eventTemplate' parameter" << e.what();
83 bool optionalMention(
false);
92 if (! optionalMention) {
94 m_mandatoryElements.push_back(m_templateDefinition->getMention());
99 m_maxCharCompatibleEvents=std::stoul(s);
113 if (! sentenceBoundsData.empty()) {
114 m_sentenceBoundsData=sentenceBoundsData;
127 LDEBUG <<
"EventTemplateMerging process";
131 auto eventData = std::dynamic_pointer_cast<EventTemplateData>(analysis.
getData(
"EventTemplateData"));
133 LERROR <<
"TemplateMerging:missing data 'EventTemplateData'";
138 if (m_useSentenceBounds) {
139 returnCode=mergeEventTemplatesOnEachSentence(analysis, eventData.get());
142 returnCode=mergeEventTemplates(eventData.get(),0,0);
145 cleanEventTemplates(eventData.get());
155 auto sb = std::dynamic_pointer_cast<SegmentationData>(analysis.
getData(m_sentenceBoundsData));
158 LERROR <<
"no sentence bounds"<< m_sentenceBoundsData <<
"defined ! abort";
162 for (
const auto& segment: sb->getSegments()) {
163 res = mergeEventTemplates(eventData,segment.getPosBegin(),segment.getPosEnd());
172bool EventTemplateMerging::ignoreTemplate(
const EventTemplate& event, uint64_t numTemplate,
173 uint64_t posBegin, uint64_t posEnd,
174 const std::set<uint64_t>& toRemove)
const
182 if (event.getPosEnd()<=posBegin || (posEnd>0 && event.getPosBegin()>=posEnd) ) {
184 LDEBUG <<
"Template"<< numTemplate <<
"ignored: not in the considered segment"
185 <<
"["<<
event.getPosBegin()<<
","<<
event.getPosEnd()<<
"]";
189 if (event.getType()!=m_templateDefinition->getMention()) {
191 LDEBUG <<
"Template"<< numTemplate <<
"ignored: not the considered event type ("<<
event.getType()<<
"/"<<m_templateDefinition->getMention()<<
")";
196 if (toRemove.find(numTemplate)!=toRemove.end()) {
198 LDEBUG <<
"Template"<< numTemplate <<
"ignored: already merged";
206LimaStatusCode EventTemplateMerging::mergeEventTemplates(EventTemplateData* eventData, uint64_t posBegin, uint64_t posEnd)
const
212 LDEBUG <<
"EventTemplateMerging::mergeEventTemplates(): merge templates of type" << m_templateDefinition->getName() <<
"in ["<<posBegin<<
","<<posEnd<<
"]";
213 LDEBUG <<
"nb events =" << eventData->size();
215 std::set<uint64_t> toRemove;
216 uint64_t numTemplate=0;
217 for (EventTemplateData::iterator it1=eventData->begin(),it_end=eventData->end();it1!=it_end;it1++,numTemplate++)
219 if (ignoreTemplate(*it1,numTemplate,posBegin,posEnd,toRemove)) {
224 EventTemplateData::iterator it2=it1;
225 uint64_t numOtherTemplate=numTemplate;
226 for (it2++,numOtherTemplate++; it2!=it_end; it2++,numOtherTemplate++)
228 if (ignoreTemplate(*it2,numOtherTemplate,posBegin,posEnd,toRemove)) {
233 if (templateElements2.empty()) {
237 LDEBUG <<
"TemplateMerging: compare templates"
238 << numTemplate <<
"and" << numOtherTemplate <<
":\n"
239 << *it1 <<
"\n" << *it2;
241 unsigned int templateToRemove(0);
245 if (mergeTemplates(*it1,*it2,numTemplate,numOtherTemplate,templateToRemove)) {
246 toRemove.insert(templateToRemove);
248 if (templateToRemove==numTemplate) {
256 for (set<uint64_t>::reverse_iterator it=toRemove.rbegin(),
257 it_end=toRemove.rend(); it!=it_end; it++)
259 LDEBUG <<
"Erase template" << (*it)+1;
260 eventData->erase(eventData->begin()+(*it));
262 LDEBUG <<
"EventTemplateMerging::mergeEventTemplates() Done";
266void EventTemplateMerging::cleanEventTemplates(EventTemplateData* eventData)
const
269 LDEBUG <<
"EventTemplateMerging::cleanEventTemplates()" << m_templateDefinition->getName();
271 if (! m_mandatoryElements.empty()) {
272 EventTemplateData::iterator it=eventData->begin();
274 while (it!=eventData->end()) {
277 for (deque<string>::const_iterator m=m_mandatoryElements.begin(),m_end=m_mandatoryElements.end();m!=m_end;m++) {
278 if (elements.find(*m)==elements.end()) {
279 LDEBUG <<
" Erase template" << n <<
"because it does not contain mandatory element" << *m <<
":" << elements;
285 it=eventData->erase(it);
293 LDEBUG <<
"EventTemplateMerging::cleanEventTemplates()" << m_templateDefinition->getName() <<
"Done";
296bool EventTemplateMerging::compatibleTemplates(
const EventTemplate& e1,
const EventTemplate& e2,
297 unsigned int numTemplate1,
unsigned int numTemplate2,
307 if (e1.getPosBegin() <= e2.getPosEnd() && e2.getPosBegin() <= e1.getPosEnd()) {
310 else if (e1.getPosBegin()>e2.getPosBegin()) {
311 posdiff=e1.getPosBegin()-e2.getPosEnd();
314 posdiff=e2.getPosBegin()-e1.getPosEnd();
316 if (posdiff >m_maxCharCompatibleEvents) {
317 LDEBUG <<
"TemplateMerging: templates"
318 << numTemplate1 <<
"and" << numTemplate2
319 <<
"not compatible: too much apart ("<< posdiff <<
"chars)";
326 std::vector<EventTemplateElement> merged;
329 std::set<std::string> alreadyMerged;
332 for (TemplateElements::const_iterator elt2=templateElements2.begin(),
333 elt2_end=templateElements2.end(); elt2!=elt2_end; )
335 const std::string& role2=(*elt2).first;
336 unsigned int cardinality=m_templateDefinition->getCardinality(role2);
338 vector<const EventTemplateElement*> values2;
341 while (elt2 != templateElements2.end() && role2 == (*elt2).first) {
342 values2.push_back(&((*elt2).second));
346 pair<TemplateElements::const_iterator,TemplateElements::const_iterator> found1=templateElements1.equal_range(role2);
347 if (found1.first!=found1.second) {
349 vector<const EventTemplateElement*> values1;
350 for (TemplateElements::const_iterator it=found1.first,it_end=found1.second;it!=it_end;++it) {
351 values1.push_back(&((*it).second));
353 if (compatibleValues(values2,values1,cardinality,merged)) {
354 for (
const auto& value: merged) {
355 mergedElements.emplace(role2,value);
357 alreadyMerged.insert(role2);
361 LDEBUG <<
"TemplateMerging: templates"
362 << numTemplate1 <<
"and" << numTemplate2
363 <<
":" << role2 <<
": incompatible values";
364 mergedElements.clear();
369 bool mappingFound=
false;
370 for (TemplateElements::const_iterator elt1=templateElements1.begin(),
371 elt1_end=templateElements1.end(); elt1!=elt1_end; )
373 const std::string& role1=(*elt1).first;
374 int mapping=m_templateDefinition->existsMapping(role1,role2);
379 vector<const EventTemplateElement*> values1;
380 while (elt1 != templateElements1.end() && role1 == (*elt1).first) {
381 values1.push_back(&((*elt1).second));
384 if (compatibleValues(values2,values1,cardinality,merged)) {
385 for (
const auto& value: merged) {
386 mergedElements.emplace(role2,value);
388 alreadyMerged.insert(role1);
392 LDEBUG <<
"TemplateMerging: templates"
393 << numTemplate1 <<
"and" << numTemplate2
394 <<
":" << role2 <<
"/" << (*elt1).first <<
": incompatible values";
395 mergedElements.clear();
405 }
while (elt1 != templateElements1.end() && role1== (*elt1).first);
408 if (! mappingFound) {
409 LDEBUG <<
"TemplateMerging: templates"
410 << numTemplate1 <<
"and" << numTemplate2
411 <<
":" << role2 <<
": not found in" << numTemplate1;
413 for (
const auto& v2: values2) {
414 mergedElements.emplace(role2,*v2);
473 for (
const auto& elt1: templateElements1) {
474 if (alreadyMerged.find(elt1.first)==alreadyMerged.end()) {
475 mergedElements.emplace(elt1.first,elt1.second);
482bool EventTemplateMerging::compatibleValues(
const std::vector<const EventTemplateElement*> values1,
483 const std::vector<const EventTemplateElement*> values2,
484 unsigned int cardinality,
485 std::vector<EventTemplateElement>& merged)
const
491 vector<bool> done(values2.size(),
false);
492 for (
const auto val1: values1) {
493 for (
unsigned int i(0),n=values2.size();i<n;i++) {
497 if (val1->isSimilar(*(values2[i]))) {
501 merged.push_back(*val1);
503 for (
unsigned int i(0),n=values2.size();i<n;i++) {
505 if (merged.size()+1>cardinality) {
509 merged.push_back(*(values2[i]));
516bool EventTemplateMerging::
517mergeTemplates(EventTemplate& e1, EventTemplate& e2,
518 unsigned int numTemplate1,
unsigned int numTemplate2,
519 unsigned int& templateToRemove)
const
547 EventTemplate* templateToModify=&e2;
550 if (e1.getTemplateElements().size() > e2.getTemplateElements().size()) {
551 if (!compatibleTemplates(e2,e1,numTemplate2,numTemplate1,mergedElements)) {
556 templateToModify=&e1;
557 templateToRemove=numTemplate2;
559 else if (!compatibleTemplates(e1,e2,numTemplate1,numTemplate2,mergedElements)) {
563 LDEBUG <<
"TemplateMerging: merge" << numTemplate1 <<
"into" << numTemplate2;
564 templateToRemove=numTemplate1;
567 templateToModify->setTemplateElements(mergedElements);
598 if (templateToRemove==numTemplate1) {
599 LDEBUG <<
"TemplateMerging: keep template" << numTemplate2 << e2;
602 LDEBUG <<
"TemplateMerging: keep template"<< numTemplate1 << e1;
This file is the main header file for the data related to annotation graphs.
#define EVENTTEMPLATEMERGING_CLASSID
#define EVENTANALYSISLOGINIT
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
std::string & getParamsValueAtKey(const std::string &key)
std::deque< std::string > & getListsValueAtKey(const std::string &key)
bool getBooleanParameter(const std::string &key)
return a message when a 'list' was not found
return a message when a 'param' was not found
Manage initialization of InitializableObjects using configuration module and parameters.
const InitializationParameters & getInitializationParameters() const
get Initialization Parameters
LimaStatusCode process(AnalysisContent &analysis) const override
Process on data in analysisContent.
void init(Common::XMLConfigurationFiles::GroupConfigurationStructure &unitConfiguration, Manager *manager) override
initialize with parameters from configuration file.
virtual ~EventTemplateMerging()
static const LinguisticResources & single()
const singleton accessor
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
std::multimap< std::string, EventTemplateElement > TemplateElements
launch exception related to the configuration file parsing