59#include "common/LimaVersion.h"
103#include <boost/algorithm/string.hpp>
104#include <boost/algorithm/string/find_format.hpp>
105#include <boost/algorithm/string/finder.hpp>
106#include <boost/format.hpp>
108#include <QtCore/QCoreApplication>
109#include <QtCore/QString>
127 template<
typename FindResultT>
131 for (
typename FindResultT::const_iterator i = Match.begin();
134 s += boost::str(boost::format(
"\\x%02x") %
static_cast<int>(*i));
142 const std::set<std::string>&dumpers,
143 const std::string& dumperId);
145int run(
int aargc,
char** aargv);
156 const QString&
meta);
164 const std::string& media,
165 const std::string& jsonGroupString);
167 const std::string
analyzeText(
const std::string& text,
168 const std::string& lang,
169 const std::string& pipeline,
170 const std::string&
meta);
174 std::shared_ptr<Lima::AnalysisContent> analysis);
218 std::map<std::string, AbstractAnalysisHandler*>
handlers;
225 std::shared_ptr< AbstractLinguisticProcessingClient >
m_client;
238 const QStringList& iqpipelines,
239 const QString& imodulePath,
240 const QString& iuser_config_path,
241 const QString& iuser_resources_path,
242 const QString& imeta) :
243 qlangs(iqlangs), qpipelines(iqpipelines), modulePath(imodulePath),
244 user_config_path(iuser_config_path), user_resources_path(iuser_resources_path), meta(imeta)
247 char* argv[2] = {(
char*)(
"LimaAnalyzer"), NULL};
248 QCoreApplication app(argc, argv);
250 if(iqlangs.size() == 0)
252 throw LimaException(
"Must initialize at least one language");
254 if(iqpipelines.size() == 0)
256 throw LimaException(
"Must initialize at least one pipeline");
259 QStringList additionalPaths({
modulePath+
"/config"});
261 auto limaConf = QString::fromUtf8(qgetenv(
"LIMA_CONF").constData());
262 if (!limaConf.isEmpty())
263 additionalPaths = limaConf.split(
LIMA_PATH_SEPARATOR, Qt::SkipEmptyParts) + additionalPaths;
271 QStringList additionalResourcePaths({
modulePath+
"/resources"});
273 auto limaRes = QString::fromUtf8(qgetenv(
"LIMA_RESOURCES").constData());
274 if (!limaRes.isEmpty())
275 additionalResourcePaths = limaRes.split(
LIMA_PATH_SEPARATOR, Qt::SkipEmptyParts) + additionalResourcePaths;
279 additionalResourcePaths);
294 std::string lpConfigFile =
"lima-analysis.xml";
295 std::string commonConfigFile =
"lima-common.xml";
296 std::string clientId =
"lima-coreclient";
298 std::string strConfigPath;
302 std::deque<std::string> pipelines;
304 pipelines.push_back(pipeline.toStdString());
309 std::deque<std::string> langs;
310 for (
const auto& lang:
qlangs)
311 langs.push_back(lang.toStdString());
321 Common::MediaticData::MediaticData::changeable().init(
322 resourcesPath.toUtf8().constData(),
323 configPath.toUtf8().constData(),
329 bool clientFactoryConfigured =
false;
330 Q_FOREACH(QString configDir, configDirs)
332 if (QFileInfo::exists(configDir +
"/" + lpConfigFile.c_str()))
340 (configDir +
"/" + lpConfigFile.c_str()));
341 LinguisticProcessingClientFactory::changeable().configureClientFactory(
346 clientFactoryConfigured =
true;
350 if(!clientFactoryConfigured)
352 std::cerr <<
"No LinguisticProcessingClientFactory were configured with"
354 <<
"and" << lpConfigFile << std::endl;
359 m_client = std::shared_ptr< AbstractLinguisticProcessingClient >(
360 std::dynamic_pointer_cast<AbstractLinguisticProcessingClient>(
361 LinguisticProcessingClientFactory::single().createClient(clientId)));
379 const std::string& pipelines,
380 const std::string& modulePath,
381 const std::string& user_config_path,
382 const std::string& user_resources_path,
383 const std::string& meta)
387 QStringList qlangs = QString::fromStdString(langs).split(
",", Qt::SkipEmptyParts);
388 QStringList qpipelines = QString::fromStdString(pipelines).split(
",", Qt::SkipEmptyParts);
390 QString::fromStdString(modulePath),
391 QString::fromStdString(user_config_path),
392 QString::fromStdString(user_resources_path),
393 QString::fromStdString(meta));
397 std::cerr <<
"Lima internal error: " << e.
what() << std::endl;
421 std::cerr <<
"Lima internal error: " << e.
what() << std::endl;
444 std::cerr <<
"Lima internal error: " << e.
what() << std::endl;
474 auto metas =
meta.split(
",", Qt::SkipEmptyParts);
475 for (
const auto& aMeta: metas)
477 auto kv = aMeta.split(
":");
480 std::cerr <<
"meta argument '"<< aMeta.toStdString() <<
"' is not of the form XXX:YYY: ignored" << std::endl;
484 metaData[kv[0].toStdString()] = kv[1].toStdString();
491 const std::string& media,
492 const std::string& jsonGroupString)
497 errorMessage = std::string(
"addPipelineUnit failed:") + pipeline +
", "
498 + media +
",\n" + jsonGroupString;
508 QJsonDocument doc = QJsonDocument::fromJson(in.toUtf8());
519 qDebug() <<
"Document is not an object" << Qt::endl;
524 qDebug() <<
"Invalid JSON...\n" << in << Qt::endl;
531 const std::string& media,
532 const std::string& jsonGroupString)
534 auto jsonGroup = QJsonDocument::fromJson(QByteArray::fromStdString(jsonGroupString)).object();
536 auto pipe = MediaProcessors::changeable().getPipelineForId(mediaid, pipeline);
547 auto pu = MediaProcessUnit::Factory::getFactory(
548 jsonGroup[
"class"].toString().toStdString())->create(
557 const std::string& lang,
558 const std::string& pipeline,
559 const std::string& meta)
562 if (m_d ==
nullptr ||
error)
570 return m_d->
analyzeText(text, lang, pipeline, meta);
574 std::cerr <<
"Lima internal error: " << e.
what() << std::endl;
582 const std::string& lang,
583 const std::string& pipeline,
584 const std::string& meta)
589 localMetaData[
"FileName"]=
"param";
590 auto qmeta = QString::fromStdString(
meta).split(
",", Qt::SkipEmptyParts);
591 for (
const auto& m: qmeta)
593 auto kv = m.split(
":");
595 localMetaData[kv[0].toStdString()] = kv[1].toStdString();
598 auto localLang = lang;
599 if (localLang.size() == 0)
601 localLang =
qlangs[0].toStdString();
603 auto localPipeline = pipeline;
604 if (localPipeline.size() == 0)
608 localMetaData[
"Lang"] = localLang;
610 QString contentText = QString::fromUtf8(text.c_str());
611 if (contentText.isEmpty())
613 std::cerr <<
"Empty input ! " << std::endl;
621 auto result = txtofs->str();
629 const std::set<std::string>&dumpers,
630 const std::string& dumperId)
632 auto ofs = std::make_shared< std::ostringstream >();
633 if (dumpers.find(dumperId)!=dumpers.end())
635 handler->
setOut(ofs.get());
640 LERROR << dumperId <<
"is not in the dumpers list";
653 QStringList featuresList;
654 for (
auto i = managers.cbegin(); i != managers.cend(); i++)
656 auto key = QString::fromUtf8(i->first.c_str());
657 if (key !=
"MACRO" && key !=
"MICRO")
661 auto value = QString::fromUtf8(i->second.getPropertySymbolicValue(lc).c_str());
664 featuresList << QString(
"%1=%2").arg(key).arg(value);
671 QTextStream featuresStream(&features);
672 if (featuresList.isEmpty())
678 for (
auto featuresListIt = featuresList.cbegin(); featuresListIt != featuresList.cend(); featuresListIt++)
680 if (featuresListIt != featuresList.cbegin())
682 featuresStream <<
"|";
684 featuresStream << *featuresListIt;
688 LDEBUG <<
"LimaAnalyzerPrivate::getFeats features:" << features;
698 LDEBUG <<
"LimaAnalyzerPrivate::collectVertexDependencyInformations";
701 auto posGraphData = std::dynamic_pointer_cast<LinguisticAnalysisStructure::AnalysisGraph>(analysis->getData(
"PosGraph"));
702 if (posGraphData ==
nullptr)
704 std::cerr <<
"Error: PosGraph has not been produced: check pipeline";
708 auto firstVertex = posGraphData->firstVertex();
709 auto lastVertex = posGraphData->lastVertex();
710 auto v = firstVertex;
711 auto [it, it_end] = boost::out_edges(v, *
posGraph);
721 syntacticData = std::dynamic_pointer_cast<SyntacticData>(analysis->getData(
"SyntacticData"));
724 syntacticData = std::make_shared<SyntacticData>(posGraphData.get(),
nullptr);
730 while (v != lastVertex)
743 if (!matches.empty())
745 for (
const auto& vx: matches)
750 .pointerValue<SpecificEntityAnnotation>();
753 for (
const auto& vse : se->vertices())
766 auto anaVertex = *anaVertices.begin();
779 for (
const auto& vse : se->vertices())
782 auto posVertex = *posVertices.begin();
808 auto [it, it_end] = boost::out_edges(v, *
posGraph);
822 std::shared_ptr<Lima::AnalysisContent> )
826 for (
auto [dit, dit_end] = boost::out_edges(dcurrent, *depGraph); dit != dit_end; dit++)
829 auto type = typeMap[*dit];
832 boost::target(*dit, *depGraph));
833 if (syntRelName !=
"")
843 auto neType = QString::fromUtf8(
"_") ;
851 for (
const auto& vx: matches)
857 pointerValue<SpecificEntityAnnotation>();
869 for (
const auto& anaVertex: anaVertices)
873 for (
const auto& vx: matches)
879 .pointerValue<SpecificEntityAnnotation>();
884 if (neType !=
"_")
break;
898 QString conllRelName =
"_";
899 int targetConllId = 0;
904 LDEBUG <<
"LimaAnalyzerPrivate::getConllRelName target saved for" << v <<
"is" << target;
913 LERROR <<
"LimaAnalyzerPrivate::getConllRelName target" << target <<
"not found in segmentation mapping";
916 LDEBUG <<
"LimaAnalyzerPrivate::getConllRelName conll target saved for " << v <<
" is " << targetConllId;
920 LDEBUG <<
"LimaAnalyzerPrivate::getConllRelName the lima dependency tag for " << v <<
" is " << relName;
928 conllRelName = relName;
933 if (conllRelName ==
"root")
941 LDEBUG <<
"LimaAnalyzerPrivate::getConllRelName no target saved for" << v;
945 LDEBUG <<
"LimaAnalyzerPrivate::getConllRelName result for" << v <<
"is" << conllRelName << targetConllId;
947 return { conllRelName, targetConllId };
962 QString::fromUtf8(
"SpecificEntity")).pointerValue<SpecificEntityAnnotation>();
976 bool SpaceAfter =
true;
978 for (
auto [outIter, outIterEnd] = boost::out_edges(v, *graph);
979 outIter != outIterEnd; outIter++)
981 auto next = boost::target(*outIter, *graph);
983 if( nt !=
nullptr && (nt->position() == ft->position()+ft->length()) )
994 return QString::fromUtf8(
static_cast<const LangData&
>(
996 .getPropertyManager(
"MICRO")
997 .getPropertySymbolicValue(morphoData.
firstValue(
This file is the main header file for the data related to annotation graphs.
A graph that stores the relations of syntactic dependency between the elements of a DependencyGraph.
#define LIMA_PATH_SEPARATOR
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.
Data used for the syntactic analyzis of texts.
const FsaStringsPool * sp
LinguisticGraph * posGraph
std::unique_ptr< LTRTextHandler > ltrTextHandler
std::unique_ptr< BowTextWriter > bowTextWriter
QMap< QString, QString > conllLimaDepMapping
QString getNeType(LinguisticGraphVertex posGraphVertex)
Gets the named entity type for the PosGraph vertex posGraphVertex if it is a specific entity.
const std::string analyzeText(const std::string &text, const std::string &lang, const std::string &pipeline, const std::string &meta)
LimaAnalyzerPrivate & operator=(const LimaAnalyzerPrivate &a)=delete
const LanguageData * languageData
std::map< LinguisticGraphVertex, int > vertexToToken
AnnotationData * annotationData
void collectDependencyInformations(std::shared_ptr< Lima::AnalysisContent > analysis)
std::unique_ptr< SimpleStreamHandler > fullXmlSimpleStreamHandler
std::map< std::string, AbstractAnalysisHandler * > handlers
std::shared_ptr< SyntacticData > syntacticData
QJsonObject objectFromString(const QString &in)
const SpecificEntityAnnotation * getSpecificEntityAnnotation(LinguisticGraphVertex v) const
~LimaAnalyzerPrivate()=default
LimaAnalyzerPrivate(const LimaAnalyzerPrivate &a)=delete
std::unique_ptr< BowTextHandler > bowTextHandler
std::pair< QString, int > getConllRelName(LinguisticGraphVertex v)
bool addPipelineUnit(const std::string &pipeline, const std::string &media, const std::string &jsonGroupString)
const Common::PropertyCode::PropertyAccessor * propertyAccessor
QString getFeats(const LinguisticAnalysisStructure::MorphoSyntacticData &morphoData)
const PropertyCodeManager * propertyCodeManager
void reset()
Reset all members used to store analysis states.
QString getMicro(LinguisticAnalysisStructure::MorphoSyntacticData &morphoData)
std::shared_ptr< AbstractLinguisticProcessingClient > m_client
void collectVertexDependencyInformations(LinguisticGraphVertex v, std::shared_ptr< Lima::AnalysisContent > analysis)
std::set< std::string > dumpers
std::map< std::string, std::string > metaData
LinguisticGraph * anaGraph
LimaAnalyzerPrivate(const QStringList &qlangs, const QStringList &qpipelines, const QString &modulePath, const QString &user_config_path, const QString &user_resources_path, const QString &meta)
QString user_resources_path
std::unique_ptr< SimpleStreamHandler > simpleStreamHandler
bool hasSpaceAfter(LinguisticGraphVertex v, LinguisticGraph *graph)
std::map< LinguisticGraphVertex, std::pair< LinguisticGraphVertex, std::string > > vertexDependencyInformations
LimaAnalyzer & operator=(const LimaAnalyzer &a)
LimaAnalyzer(const std::string &langs, const std::string &pipelines, const std::string &modulePath, const std::string &user_config_path="", const std::string &user_resources_path="", const std::string &meta="")
friend class LimaAnalyzerPrivate
std::string analyzeText(const std::string &text, const std::string &lang="", const std::string &pipeline="", const std::string &meta="")
bool addPipelineUnit(const std::string &pipeline, const std::string &media, const std::string &jsonGroupString)
defines callback interface
virtual void setOut(std::ostream *out)=0
set the output stream.
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
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 PropertyAccessor & getPropertyAccessor(const std::string &propertyName) const
Get the PropertyAccessor associated to a property.
Parser class for the lima's xml configuration files.
Use this exception to signal an error in one of the configuration files.
The main LIMA exception class.
virtual const char * what() const override
Holds morphosyntactic informations.
LinguisticCode firstValue(const Common::PropertyCode::PropertyAccessor &propertyAccessor) const
Return the first non empty value for the given accessor.
A representation of a specific entity to store in the annotation graph.
static const AmosePluginsManager & single()
const singleton accessor
static AmosePluginsManager & changeable()
singleton accessor
originally detectGroupConfigurationStructure.h in detectlibraries
bool hasAnnotation(AnnotationGraphVertex v, const LimaString &annot) const
int run(int aargc, char **aargv)
std::shared_ptr< std::ostringstream > openHandlerOutputString(AbstractTextualAnalysisHandler *handler, const std::set< std::string > &dumpers, const std::string &dumperId)
QStringList buildResourcesDirectoriesList(const QStringList &projects, const QStringList &paths)
Build a list of resources directories from a list of project names and a list of paths.
QStringList buildConfigurationDirectoriesList(const QStringList &projects, const QStringList &paths)
Build a list of configuration directories from a list of project names and a list of paths.
LIMA_COMMONQSLOG_EXPORT bool initQsLog(const QString &configString)
std::string operator()(const FindResultT &Match) const