55namespace LinguisticProcessing
58namespace AnalysisDumpers
61QStringList
FORMATS = {
"CoNLL-U",
"CoNLL-03"};
73 std::shared_ptr<DumperStream>& dstream,
77 std::map<LinguisticGraphVertex,int>& segmentationMapping,
78 const QString& neType,
85 std::shared_ptr<DumperStream>& dstream,
90 const QString& parentNeType,
99 std::pair<QString, QString> getConllRelName(
101 std::map<LinguisticGraphVertex,int>& segmentationMapping);
114 std::map<int, size_t>& out);
119 void dumpNamedEntity(std::shared_ptr<DumperStream>& dstream,
123 std::map<LinguisticGraphVertex,int>& segmentationMapping,
124 const QString& neType);
130 void collectPredicateTokens(
136 std::shared_ptr<DumperStream>& dstream,
138 const QString& inflectedToken,
139 const QString& lemmatizedToken,
140 const QString& micro,
142 const QString& features,
143 const QString& targetConllIdString,
144 const QString& conllRelName,
146 const QStringList& miscField,
147 const QString& neType,
148 const QString& previousNeType);
153 QString m_format =
"CoNLL-U";
156 bool m_withColsHeader;
158 QMap<QString, QString> m_conllLimaDepMapping;
167 const std::map< std::string, PropertyManager >* managers;
169 QMultiMap<LinguisticGraphVertex, AnnotationGraphVertex> predicates;
170 QString previousNeType;
173 std::string> > vertexDependencyInformations;
176ConllDumperPrivate::ConllDumperPrivate():
178 m_withColsHeader(false),
180 m_conllLimaDepMapping(),
184 annotationData(nullptr),
222 m_d->m_withColsHeader= QString(
224 "withColsHeader").c_str() ).toLower() ==
"true";
233 "mappingFile").c_str());
234 std::ifstream ifs(mappingFile.toStdString(), std::ifstream::binary);
237 LERROR <<
"ERROR: cannot open" << mappingFile;
240 while (ifs.good() && !ifs.eof())
243 QStringList strs = QString::fromUtf8(line.c_str()).split(
'\t');
244 if (strs.size() == 2)
246 m_d->m_conllLimaDepMapping.insert(strs[0],strs[1]);
253 LINFO <<
"no parameter 'mappingFile' in ConllDumper group" <<
" !";
259 m_d->m_format = QString::fromStdString(
261 if (!
FORMATS.contains(m_d->m_format))
263 QString errorMessage;
264 QTextStream qts(&errorMessage);
265 qts <<
"Invalid CoNLL dumper configuration. Known formats are"
266 <<
FORMATS.join(
",") <<
". Got" << m_d->m_format;
279 LDEBUG <<
"ConllDumper::process";
282 auto metadata = std::dynamic_pointer_cast<LinguisticMetaData>(analysis.
getData(
"LinguisticMetaData"));
286 LERROR <<
"ConllDumper::process no LinguisticMetaData ! abort";
290 auto annotationData = std::dynamic_pointer_cast<AnnotationData>(analysis.
getData(
"AnnotationData"));
291 if (annotationData ==
nullptr)
294 LINFO <<
"ConllDumper::process no AnnotationData ! Will not contain NE nor predicates";
296 m_d->annotationData = annotationData.get();
297 auto posGraphData=std::dynamic_pointer_cast<AnalysisGraph>(analysis.
getData(m_d->m_graph.toStdString()));
302 LERROR <<
"ConllDumper::process graph" << m_d->m_graph <<
"has not been produced: check pipeline";
305 auto posGraph = posGraphData->getGraph();
306 m_d->posGraph = posGraph;
308 auto anaGraphData=std::dynamic_pointer_cast<AnalysisGraph>(analysis.
getData(
"AnalysisGraph"));
312 LERROR <<
"ConllDumper::process graph AnalysisGraph has not been produced: check pipeline";
315 auto anaGraph = anaGraphData->getGraph();
316 m_d->anaGraph = anaGraph;
318 auto sd = std::dynamic_pointer_cast<SegmentationData>(analysis.
getData(
"SentenceBoundaries"));
322 LERROR <<
"ConllDumper::process no SentenceBoundaries! abort";
326 auto syntacticData = std::dynamic_pointer_cast<SyntacticData>(analysis.
getData(
"SyntacticData"));
327 if (syntacticData ==
nullptr)
329 syntacticData = std::make_shared<SyntacticData>(posGraphData.get(),
nullptr);
330 syntacticData->setupDependencyGraph();
331 analysis.
setData(
"SyntacticData", syntacticData);
333 auto depGraph = syntacticData-> dependencyGraph();
334 m_d->depGraph = depGraph;
338 uint64_t nbSentences((sd->getSegments()).size());
339 if (nbSentences == 0)
342 LERROR <<
"ConllDumper::process 0 sentence to process";
346 auto sbItr = sd->getSegments().begin();
348 LDEBUG <<
"ConllDumper::process There are "<< nbSentences <<
" sentences";
350 auto sentenceBegin = sbItr->getFirstVertex();
351 auto sentenceEnd = sbItr->getLastVertex();
353 auto limaConllTokenIdMapping = std::dynamic_pointer_cast<LimaConllTokenIdMapping>(
354 analysis.
getData(
"LimaConllTokenIdMapping"));
355 if (limaConllTokenIdMapping ==
nullptr)
357 limaConllTokenIdMapping = std::make_shared<LimaConllTokenIdMapping>();
358 analysis.
setData(
"LimaConllTokenIdMapping", limaConllTokenIdMapping);
363 const auto originalText = std::dynamic_pointer_cast<LimaStringText>(analysis.
getData(
"Text"));
365 if (m_d->m_format ==
"CoNLL-U")
368 else if (m_d->m_format ==
"CoNLL-03")
370 dstream->out() <<
"-DOCSTART- -X- O O" << std::endl << std::endl;
375 QString errorMessage;
376 QTextStream qts(&errorMessage);
377 qts <<
"ConllDumper::process unknown format" << m_d->m_format;
381 while (sbItr != sd->getSegments().end())
385 if (m_d->m_format ==
"CoNLL-U")
387 if( sentenceNb==1 && m_d->m_withColsHeader )
390 <<
"# global.columns = ID\tFORM\tLEMMA\tUPOS\tXPOS\tFEATS\tHEAD\tDEPREL\tDEPS\tMISC"
393 dstream->out() <<
"# sent_id = " << sentenceNb << std::endl;
395 else if (m_d->m_format ==
"CoNLL-03")
401 QString errorMessage;
402 QTextStream qts(&errorMessage);
403 qts <<
"ConllDumper::process unknown format" << m_d->m_format;
407 sentenceBegin=sbItr->getFirstVertex();
408 sentenceEnd=sbItr->getLastVertex();
409 std::map<LinguisticGraphVertex,int> segmentationMapping;
410 std::map<int,LinguisticGraphVertex> segmentationMappingReverse;
411 std::map<int,size_t> transducedTokens;
412 m_d->getTransducedTokens(*anaGraph, sentenceBegin, sentenceEnd, transducedTokens);
415 LDEBUG <<
"ConllDumper::process begin - end: " << sentenceBegin
416 <<
" - " << sentenceEnd;
420 QQueue<LinguisticGraphVertex> toVisit;
421 QSet<LinguisticGraphVertex> visited;
422 toVisit.enqueue(sentenceBegin);
425 while (v != sentenceEnd && !toVisit.empty())
427 v = toVisit.dequeue();
429 LDEBUG <<
"ConllDumper::process Vertex index : " << v;
432 segmentationMapping.insert(std::make_pair(v,vertexId));
433 segmentationMappingReverse.insert(std::make_pair(vertexId,v));
435 LDEBUG <<
"ConllDumper::process conll id : " << vertexId
436 <<
" Lima id : " << v;
439 auto dcurrent = syntacticData->depVertexForTokenVertex(v);
441 boost::tie(dit,dit_end) = boost::out_edges(dcurrent,*depGraph);
442 for (; dit != dit_end; dit++)
445 LDEBUG <<
"ConllDumper::process Dumping dependency edge "
446 << (*dit).m_source <<
" -> " << (*dit).m_target;
451 auto type = typeMap[*dit];
454 LDEBUG <<
"ConllDumper::process relation = " << syntRelName;
455 LDEBUG <<
"ConllDumper::process Src : Dep vertex= "
456 << boost::source(*dit, *depGraph);
457 auto src = syntacticData->tokenVertexForDepVertex(
458 boost::source(*dit, *depGraph));
459 LDEBUG <<
"ConllDumper::process Src : Morph vertex= " << src;
460 LDEBUG <<
"ConllDumper::process Targ : Dep vertex= "
461 << boost::target(*dit, *depGraph);
463 auto dest = syntacticData->tokenVertexForDepVertex(
464 boost::target(*dit, *depGraph));
466 LDEBUG <<
"ConllDumper::process Targ : Morph vertex= " << dest;
471 LDEBUG <<
"ConllDumper::process saving target for"
472 << v <<
":" << dest << syntRelName;
474 m_d->vertexDependencyInformations.insert(
475 std::make_pair(v, std::make_pair(dest, syntRelName)));
478 catch (
const std::range_error& )
484 LDEBUG <<
"ConllDumper::process: catch others.....";
489 if (v == sentenceEnd)
494 for (boost::tie(outItr,outItrEnd)=boost::out_edges(v, *posGraph);
495 outItr!=outItrEnd; outItr++)
498 if (!visited.contains(next) && next != posGraphData->lastVertex())
500 toVisit.enqueue(next);
513 sentenceBegin=sbItr->getFirstVertex();
514 sentenceEnd=sbItr->getLastVertex();
517 m_d->collectPredicateTokens( analysis,
521 LDEBUG <<
"ConllDumper::process predicates for sentence between"
522 << sentenceBegin <<
"and" << sentenceEnd <<
"are:" << m_d->predicates;
524 auto keys = m_d->predicates.keys();
527 bool firstTime =
true;
530 while (v != sentenceEnd)
535 if( ft !=
nullptr && v != sentenceBegin )
539 pStart = ft->position();
542 pEnd = ft->position() + ft->length();
545 for (boost::tie(outIter,outIterEnd) = boost::out_edges(v,*posGraph);
546 outIter!=outIterEnd; outIter++)
548 v = boost::target(*outIter,*posGraph);
553 LERROR <<
"ConllDumper::process sentence traversal loop stalls on" << v <<
"; breaking out.";
557 auto curSentenceText = originalText->mid(pStart-1, pEnd-pStart+1);
559 if (m_d->m_format ==
"CoNLL-U")
562 dstream->out() <<
"# text = "
563 << curSentenceText.replace(
"\r\n",
" ").replace(
"\n",
" ").toStdString()
566 else if (m_d->m_format ==
"CoNLL-03") {}
570 QString errorMessage;
571 QTextStream qts(&errorMessage);
572 qts <<
"ConllDumper::process unknown format" << m_d->m_format;
577 toVisit.enqueue(sentenceBegin);
580 while (!toVisit.empty() && v!=sentenceEnd)
582 v = toVisit.dequeue();
584 if (transducedTokens.find(tokenId) != transducedTokens.end())
586 int firstTokenId = tokenId;
587 int lastTokenId = tokenId + transducedTokens[tokenId] - 1;
592 LWARN <<
"Empty token for vertex" <<
vertex_token <<
"in graph" << anaGraphData->getGraphId();
594 else if (ft->orthographicAlternatives().size() > 0)
596 StringsPoolIndex idx = *(ft->orthographicAlternatives().begin());
597 tokenForm = (*m_d->sp)[idx];
599 if (m_d->m_format ==
"CoNLL-U")
600 dstream->out() << firstTokenId <<
"-" << lastTokenId
601 <<
"\t" << tokenForm.toStdString()
614 m_d->dumpPosGraphVertex(dstream,
624 LDEBUG <<
"ConllDumper::process look at out edges of" << v;
627 for (boost::tie(outIter,outIterEnd) = boost::out_edges(v,*posGraph);
628 outIter != outIterEnd; outIter++)
632 LDEBUG <<
"ConllDumper::process looking out vertex" << next;
634 if (!visited.contains(next))
637 LDEBUG <<
"ConllDumper::process enqueuing" << next;
639 visited.insert(next);
640 toVisit.enqueue(next);
643 if (v == sentenceEnd)
649 limaConllTokenIdMapping->insert(std::make_pair(sentenceNb,
650 segmentationMappingReverse));
653 if (sbItr != sd->getSegments().end())
655 dstream->out() << std::endl;
667 for (
const auto& vx: annotationData->matches(
"PosGraph", v,
"annot"))
669 if (annotationData->
hasAnnotation(vx, QString::fromUtf8(
"SpecificEntity")))
686 std::shared_ptr<DumperStream>& dstream,
690 std::map<LinguisticGraphVertex,int>& segmentationMapping,
691 const QString& parentNeType,
696 LDEBUG <<
"ConllDumperPrivate::dumpPosGraphVertex IN" << v;
698 if (anaGraph ==
nullptr || posGraph ==
nullptr || depGraph ==
nullptr
699 || annotationData ==
nullptr)
702 LERROR <<
"ConllDumperPrivate::dumpPosGraphVertex missing data";
711 if( morphoData != 0 && ft != 0
712 && ((!morphoData->empty()) || ft->length() > 0) && notDone )
715 LDEBUG <<
"ConllDumperPrivate::dumpPosGraphVertex PosGraph nb different LinguisticCode"
716 << morphoData->size();
719 auto micro = getMicro(morphoData);
721 LDEBUG <<
"ConllDumperPrivate::dumpPosGraphVertex graphTag:" << micro;
724 auto feats = getFeats(morphoData);
726 LDEBUG <<
"ConllDumperPrivate::dumpPosGraphVertex feats:" << feats;
729 auto inflectedToken = ft->stringForm().toStdString();
730 if (inflectedToken.find_first_of(
"\r\n\t") != std::string::npos)
731 boost::find_format_all(inflectedToken,
732 boost::token_finder(!boost::is_print()),
735 QString lemmatizedToken;
736 if (morphoData != 0 && !morphoData->empty())
738 lemmatizedToken = (*sp)[(*morphoData)[0].lemma];
742 QString neType = getNeType(v);
752 dumpNamedEntity(dstream, v, tokenId, vEndDone, segmentationMapping, neType);
756 if (!parentNeType.isEmpty())
758 neType = parentNeType;
761 QString conllRelName;
762 QString targetConllIdString;
763 std::tie(conllRelName,
764 targetConllIdString) = getConllRelName(v, segmentationMapping);
766 QStringList miscField;
770 LDEBUG <<
"ConllDumperPrivate::dumpPosGraphVertex specific entity type is"
773 miscField << (QString(
"NE=") + (first?
"B-":
"I-") + neType);
774 const auto annot = getSpecificEntityAnnotation(v);
776 LDEBUG <<
"ConllDumperPrivate::dumpPosGraphVertex specific entity annotation is"
779 if (annot !=
nullptr)
781 const auto& features = annot->getFeatures();
782 for (
const auto& feature: features)
784 QString featureString;
785 QTextStream qts(&featureString);
787 && !feature.getName().empty()
788 && !feature.getValueString().empty())
790 qts <<
"NE-" << QString::fromStdString(feature.getName()) <<
"=";
792 QString::fromStdString(feature.getValueString()));
794 miscField << featureString;
799 miscField << (QString(
"Pos=") + QString::number(ft->position()) );
800 miscField << (QString(
"Len=") + QString::number(ft->length()) );
802 if(!hasSpaceAfter(v, posGraph))
804 miscField << QString(
"SpaceAfter=No");
807 miscField << getPredicate(v);
809 if (miscField.empty())
816 QString::fromStdString(inflectedToken),
828 previousNeType = neType;
841 QMultiMap<LinguisticGraphVertex, AnnotationGraphVertex> result;
843 auto annotationData = std::dynamic_pointer_cast<AnnotationData>(analysis.
getData(
"AnnotationData"));
844 if (annotationData ==
nullptr)
847 LERROR <<
"No annotation data exists: check pipeline";
852 auto tokenList = std::dynamic_pointer_cast<AnalysisGraph>(analysis.
getData(m_graph.toStdString()));
853 if (tokenList ==
nullptr)
856 LERROR <<
"graph" << m_graph <<
"has not been produced: check pipeline";
860 auto graph = tokenList->getGraph();
862 QQueue<LinguisticGraphVertex> toVisit;
863 QSet<LinguisticGraphVertex> visited;
864 toVisit.enqueue(sentenceBegin);
866 while (v != sentenceEnd && !toVisit.empty())
868 v = toVisit.dequeue();
870 LDEBUG <<
"ConllDumperPrivate::collectPredicateTokens vertex:" << v;
874 auto vMatches = annotationData->
matches(m_graph.toStdString(), v,
"annot");
875 for (
const auto& vMatch : vMatches)
880 LDEBUG <<
"ConllDumperPrivate::collectPredicateTokens insert"
883 result.insert(v, vMatch);
887 for (boost::tie(outItr,outItrEnd)=boost::out_edges(v,*graph);
888 outItr!=outItrEnd; outItr++)
890 auto next = boost::target(*outItr, *graph);
891 if (!visited.contains(next) && next != tokenList->lastVertex())
893 toVisit.enqueue(next);
902 auto neType = QString::fromUtf8(
"_") ;
903 if (annotationData !=
nullptr)
906 auto matches = annotationData->
matches(m_graph.toStdString(), posGraphVertex,
"annot");
907 for (
const auto& vx: matches)
910 vx, QString::fromUtf8(
"SpecificEntity")))
912 auto se = annotationData->
annotation(vx, QString::fromUtf8(
"SpecificEntity")).
913 pointerValue<SpecificEntityAnnotation>();
922 auto anaVertices = annotationData->
matches(m_graph.toStdString(), posGraphVertex,
925 for (
const auto& anaVertex: anaVertices)
927 auto matches = annotationData->
matches(
"AnalysisGraph",
930 for (
const auto& vx: matches)
933 vx, QString::fromUtf8(
"SpecificEntity")))
936 vx, QString::fromUtf8(
"SpecificEntity"))
942 if (neType !=
"_")
break;
949std::pair<QString, QString> ConllDumperPrivate::getConllRelName(
951 std::map<LinguisticGraphVertex,int>& segmentationMapping)
955 LDEBUG <<
"ConllDumperPrivate::getConllRelName" << v;
957 QString conllRelName =
"_";
958 int targetConllId = 0;
959 if (vertexDependencyInformations.count(v) != 0)
961 auto target = vertexDependencyInformations.find(v)->second.first;
963 LDEBUG <<
"ConllDumper::process target saved for"
964 << v <<
"is" << target;
966 if (segmentationMapping.find(target) != segmentationMapping.end())
968 targetConllId = segmentationMapping.find(target)->second;
973 LERROR <<
"ConllDumper::process target" << target
974 <<
"not found in segmentation mapping";
977 LDEBUG <<
"ConllDumper::process conll target saved for "
978 << v <<
" is " << targetConllId;
980 auto relName = QString::fromUtf8(
981 vertexDependencyInformations.find(v)->second.second.c_str());
983 LDEBUG <<
"ConllDumper::process the lima dependency tag for "
984 << v <<
" is " << relName;
986 if (m_conllLimaDepMapping.contains(relName))
988 conllRelName = m_conllLimaDepMapping[relName];
992 conllRelName = relName;
997 if (conllRelName ==
"root")
1002 QString targetConllIdString = QString(QLatin1String(
"%1")).arg(targetConllId);
1004 return { conllRelName, targetConllIdString };
1011 LDEBUG <<
"ConllDumperPrivate::getPredicate" << v;
1013 QStringList miscField;
1014 if (annotationData !=
nullptr && predicates.contains(v))
1016 auto keys = predicates.keys();
1022 LDEBUG <<
"ConllDumper::process output the roles for the"
1023 << keys.size() <<
"predicates";
1025 for (
int i = 0; i < keys.size(); i++)
1027 auto predicateVertex = predicates.value(keys[keys.size()-1-i]);
1029 auto vMatches = annotationData->
matches(m_graph.toStdString(), v,
"annot");
1030 if (!vMatches.empty())
1033 LDEBUG <<
"ConllDumper::process there is" << vMatches.size()
1034 <<
"nodes matching PoS graph vertex" << v
1035 <<
"in the annotation graph.";
1037 QString roleAnnotation;
1038 for (
auto it = vMatches.begin(); it != vMatches.end(); it++)
1042 boost::tie(vMatchInEdgesIt, vMatchInEdgesIt_end) =
1043 boost::in_edges(vMatch,annotationData->
getGraph());
1044 for (; vMatchInEdgesIt != vMatchInEdgesIt_end; vMatchInEdgesIt++)
1046 auto inVertex = boost::source(*vMatchInEdgesIt,
1048 auto inVertexAnnotPosGraphMatches = annotationData->
matches(
1049 "annot",inVertex,m_graph.toStdString());
1050 if (inVertex == predicateVertex
1051 && !inVertexAnnotPosGraphMatches.empty())
1061 if (!roleAnnotation.isEmpty() )
1062 predicate = roleAnnotation +
":" + predicate;
1065 if (!predicate.isEmpty())
1067 miscField << predicate;
1077 bool SpaceAfter =
true;
1079 for (boost::tie(outIter,outIterEnd) = boost::out_edges(v, *graph);
1080 outIter!=outIterEnd; outIter++)
1082 auto next = boost::target(*outIter, *graph);
1085 && (nt->position() == ft->position()+ft->length()) )
1096 return QString::fromUtf8(
static_cast<const LangData&
>(
1098 .getPropertyManager(
"MICRO")
1099 .getPropertySymbolicValue(morphoData->
firstValue(
1100 *m_propertyAccessor)).c_str());
1109 QStringList featuresList;
1110 for (
auto i = managers->cbegin(); i != managers->cend(); i++)
1112 auto key = QString::fromUtf8(i->first.c_str());
1113 if (key !=
"MACRO" && key !=
"MICRO")
1117 auto value = QString::fromUtf8(i->second.getPropertySymbolicValue(lc).c_str());
1118 if (value !=
"NONE")
1120 featuresList << QString(
"%1=%2").arg(key).arg(value);
1125 featuresList.sort();
1127 QTextStream featuresStream(&features);
1128 if (featuresList.isEmpty())
1134 for (
auto featuresListIt = featuresList.cbegin(); featuresListIt != featuresList.cend(); featuresListIt++)
1136 if (featuresListIt != featuresList.cbegin())
1138 featuresStream <<
"|";
1140 featuresStream << *featuresListIt;
1144 LDEBUG <<
"ConllDumper::process features:" << features;
1150void ConllDumperPrivate::getTransducedTokens(
const LinguisticGraph& graph,
1153 std::map<int, size_t>& out)
1155 QQueue<LinguisticGraphVertex> toVisit;
1156 QSet<LinguisticGraphVertex> visited;
1158 toVisit.enqueue(begin);
1161 int firstTransducedTokenId = -1;
1162 uint64_t prev_pos = 0;
1164 while (!toVisit.empty() && v != end)
1167 v = toVisit.dequeue();
1171 if (ft !=
nullptr && prev_pos > 0 && prev_pos == ft->
position())
1173 if (firstTransducedTokenId >= 0)
1175 out[firstTransducedTokenId] += 1;
1180 throw std::runtime_error(
"token id should not be null");
1181 out[tokenId - 1] = 2;
1182 firstTransducedTokenId = tokenId - 1;
1187 firstTransducedTokenId = -1;
1199 for (boost::tie(outIter,outIterEnd) = boost::out_edges(v,graph);
1200 outIter != outIterEnd; outIter++)
1202 auto next = boost::target(*outIter, graph);
1203 if (!visited.contains(next))
1205 visited.insert(next);
1206 toVisit.enqueue(next);
1213QString
matchesS(
const std::set<AnnotationGraphVertex>& s)
1216 QTextStream qts(&result);
1217 for (
auto i: s) {qts << i <<
",";}
1221void ConllDumperPrivate::dumpNamedEntity(std::shared_ptr<DumperStream>& dstream,
1225 std::map<LinguisticGraphVertex,int>& segmentationMapping,
1226 const QString& neType)
1230 LDEBUG <<
"ConllDumperPrivate::dumpNamedEntity" << v << tokenId << vEndDone
1239 if (annotationData !=
nullptr)
1242 auto matches = annotationData->
matches(m_graph.toStdString(), v,
"annot");
1244 LDEBUG <<
"ConllDumperPrivate::dumpNamedEntity matches PosGraph" << v
1247 for (
const auto& vx: matches)
1250 vx, QString::fromUtf8(
"SpecificEntity")))
1253 QString::fromUtf8(
"SpecificEntity"))
1255 previousNeType =
"O";
1257 for (
const auto& vse : se->vertices())
1259 dumpPosGraphVertex(dstream, vse, tokenId, vEndDone,
1260 segmentationMapping, neType, first);
1264 LDEBUG <<
"ConllDumperPrivate::dumpNamedEntity return after SpecificEntity annotation on PosGraph";
1269 auto anaVertices = annotationData->
matches(m_graph.toStdString(), v,
"AnalysisGraph");
1271 LDEBUG <<
"ConllDumperPrivate::dumpNamedEntity anaVertices for" << v
1275 assert(anaVertices.size() == 1);
1276 auto anaVertex = *anaVertices.begin();
1278 LDEBUG <<
"ConllDumperPrivate::dumpNamedEntity anaVertex is" << anaVertex;
1281 anaVertex, QString::fromUtf8(
"SpecificEntity")))
1283 auto se = annotationData->
annotation(anaVertex,
1284 QString::fromUtf8(
"SpecificEntity"))
1287 LDEBUG <<
"ConllDumperPrivate::dumpNamedEntity anaVertex se ("
1288 << (*sp)[se->getString()]
1289 <<
") annotation vertices are" << se->
vertices()
1290 <<
"and normalized form:" << (*sp)[se->getNormalizedForm()]
1291 <<
"and features:" << se->getFeatures();
1297 previousNeType =
"O";
1299 for (
const auto& vse : se->vertices())
1301 dumpAnalysisGraphVertex(dstream, vse, v, tokenId, vEndDone, neType,
1302 first, se->getFeatures());
1305 previousNeType = neType;
1312 std::shared_ptr<DumperStream>& dstream,
1317 const QString& neType,
1324 LDEBUG <<
"ConllDumperPrivate::dumpAnalysisGraphVertex" << v << posGraphVertex
1327 if (anaGraph ==
nullptr || posGraph ==
nullptr || depGraph ==
nullptr
1328 || annotationData ==
nullptr)
1331 LERROR <<
"ConllDumperPrivate::dumpAnalysisGraphVertex missing data";
1341 LDEBUG <<
"ConllDumperPrivate::dumpAnalysisGraphVertex PosGraph token" << v;
1343 if( morphoData != 0 && ft != 0
1344 && ((!morphoData->empty()) || ft->
length() > 0) && notDone )
1347 LDEBUG <<
"ConllDumperPrivate::dumpAnalysisGraphVertex PosGraph nb different LinguisticCode"
1348 << morphoData->size();
1351 auto micro = getMicro(morphoData);
1353 LDEBUG <<
"ConllDumperPrivate::dumpAnalysisGraphVertex micro:" << micro;
1356 auto feats = getFeats(morphoData);
1358 LDEBUG <<
"ConllDumperPrivate::dumpAnalysisGraphVertex feats:" << feats;
1361 auto inflectedToken = ft->
stringForm().toStdString();
1362 if (inflectedToken.find_first_of(
"\r\n\t") != std::string::npos)
1363 boost::find_format_all(inflectedToken,
1364 boost::token_finder(!boost::is_print()),
1367 QString lemmatizedToken;
1368 if (morphoData != 0 && !morphoData->empty())
1370 lemmatizedToken = (*sp)[(*morphoData)[0].lemma];
1379 QString conllRelName =
"_";
1380 QString targetConllIdString =
"_";
1382 QStringList miscField;
1386 LDEBUG <<
"ConllDumperPrivate::dumpAnalysisGraphVertex specific entity type is" << neType;
1387 LDEBUG <<
"ConllDumperPrivate::dumpAnalysisGraphVertex posGraphVertex is" << posGraphVertex;
1389 miscField << (QString(
"NE=") + (first?
"B-":
"I-") + neType);
1390 for (
const auto& feature: features)
1392 if(!feature.getName().empty()
1393 && !feature.getValueString().empty())
1395 QString featureString;
1396 QTextStream qts(&featureString);
1397 qts <<
"NE-" << QString::fromStdString(feature.getName()) <<
"=";
1399 QString::fromStdString(feature.getValueString()));
1400 miscField << featureString;
1405 miscField << (QString(
"Pos=") + QString::number(ft->
position()) );
1406 miscField << (QString(
"Len=") + QString::number(ft->
length()) );
1408 if(!hasSpaceAfter(v, anaGraph))
1410 miscField << QString(
"SpaceAfter=No");
1413 miscField << getPredicate(v);
1415 if (miscField.empty())
1421 QString::fromStdString(inflectedToken),
1426 targetConllIdString,
1437void ConllDumperPrivate::dumpToken(
1438 std::shared_ptr<DumperStream>& dstream,
1440 const QString& inflectedToken,
1441 const QString& lemmatizedToken,
1442 const QString& micro,
1443 const QString& xpos,
1444 const QString& features,
1445 const QString& targetConllIdString,
1446 const QString& conllRelName,
1447 const QString& deps,
1448 const QStringList& miscField,
1449 const QString& neType,
1450 const QString& previousNeType)
1454 LDEBUG <<
"ConllDumperPrivate::dumpToken" << tokenId;
1456 if (m_format ==
"CoNLL-U")
1483 dstream->out() << tokenId++
1484 <<
"\t" << inflectedToken.toStdString()
1485 <<
"\t" << lemmatizedToken.toStdString()
1486 <<
"\t" << micro.toStdString()
1487 <<
"\t" << xpos.toStdString()
1488 <<
"\t" << features.toStdString()
1489 <<
"\t" << targetConllIdString.toStdString()
1490 <<
"\t" << conllRelName.toStdString()
1491 <<
"\t" << deps.toStdString()
1492 <<
"\t" << miscField.join(
'|').toStdString();
1493 dstream->out() << std::endl;
1495 else if (m_format ==
"CoNLL-03")
1508 LDEBUG <<
"ConllDumperPrivate::dumpToken" << tokenId
1509 << inflectedToken.toStdString() << neType << previousNeType;
1511 QString inflectedTokenEscaped = inflectedToken;
1512 inflectedTokenEscaped.replace(
" ",
"_");
1513 dstream->out() << inflectedTokenEscaped.toStdString()
1514 <<
" " << micro.toStdString()
1516 if (neType.isEmpty() || neType ==
"_")
1518 dstream->out() <<
" " <<
"O";
1522 if (neType == previousNeType)
1524 dstream->out() <<
" " <<
"I-";
1528 dstream->out() <<
" " <<
"B-";
1530 dstream->out() << neType.toStdString();
1532 dstream->out() << std::endl;
1537 QString errorMessage;
1538 QTextStream qts(&errorMessage);
1539 qts <<
"ConllDumper::dumpToken unknown format" << m_format;
1541 throw std::runtime_error(errorMessage.toStdString());
This file is the main header file for the data related to annotation graphs.
A graph that stores any data (annotations) referencing primarily nodes of a text anlaysis.
#define CONLLDUMPER_CLASSID
DependencyGraph::out_edge_iterator DependencyGraphOutEdgeIt
boost::adjacency_list< boost::vecS, boost::vecS, boost::bidirectionalS, DepVertexProperties, DepEdgeProperties > DependencyGraph
The dependency graph class.
A graph structure for linguistic analysis.
LinguisticGraph::vertex_descriptor LinguisticGraphVertex
LinguisticGraph::out_edge_iterator LinguisticGraphOutEdgeIt
boost::adjacency_list< boost::vecS, boost::vecS, boost::bidirectionalS, LinguisticVertexProperties > LinguisticGraph
Property to identify the chains in the graph.
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.
const GenericAnnotation & annotation(AnnotationGraphVertex v1, AnnotationGraphVertex v2, const LimaString &annot) const
const LimaString & stringAnnotation(AnnotationGraphVertex v1, AnnotationGraphVertex v2, const LimaString &annot) const
ValueType * pointerValue()
Provide function to read write and check a property.
Provide tools to parse a property file, and deal with the property coding system.
const std::map< std::string, PropertyManager > & getPropertyManagers() const
Get the map of all PropertyManagers.
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.
std::string & getParamsValueAtKey(const std::string &key)
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
Use this exception to signal an error in one of the configuration files.
std::shared_ptr< DumperStream > initialize(AnalysisContent &analysis) const
virtual void init(Common::XMLConfigurationFiles::GroupConfigurationStructure &unitConfiguration, Manager *manager) override
initialize with parameters from configuration file.
This dumper outputs analysis result in various CoNLL formats.
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.
a list of generic features: each feature is unique (only one feature for a name)
Holds morphosyntactic informations.
LinguisticCode firstValue(const Common::PropertyCode::PropertyAccessor &propertyAccessor) const
Return the first non empty value for the given accessor.
holds surface data of a token
uint64_t position() const
const LimaString & stringForm() const
A representation of a specific entity to store in the annotation graph.
const std::vector< LinguisticGraphVertex > & vertices() const
static const MediaticData & single()
const singleton accessor
AnnotationGraph & getGraph()
AnnotationGraph::in_edge_iterator AnnotationGraphInEdgeIt
bool hasStringAnnotation(AnnotationGraphVertex v, const LimaString &annot) const
bool hasAnnotation(AnnotationGraphVertex v, const LimaString &annot) const
std::string readLine(std::istream &inputFile)
LimaString transcodeToXmlEntities(const LimaString &str)
QString findFileInPaths(const QString &paths, const QString &fileName, const QChar &separator)
Find the given file in the given paths.
SimpleFactory< MediaProcessUnit, ConllDumper > conllDumperFactory(CONLLDUMPER_CLASSID)
QString matchesS(const std::set< AnnotationGraphVertex > &s)
launch exception related to the configuration file parsing