6#ifndef DEEPLIMA_TOKEN_SEQUENCE_ANALYZER
7#define DEEPLIMA_TOKEN_SEQUENCE_ANALYZER
12#include <unordered_map>
13#include <unordered_set>
15#include <unicode/unistr.h>
16#include <unicode/ustream.h>
17#include "unicode/utypes.h"
33template<>
struct std::hash<
deeplima::morph_model::morph_feats_t> {
56 typedef std::function < void (std::shared_ptr< StringIndex > stridx,
58 const std::vector<StringIndex::idx_t>& lemmata,
65 virtual const std::vector<std::vector<std::string>>&
get_classes()
const = 0;
69 virtual std::shared_ptr<StringIndex>
get_stridx()
const = 0;
73 virtual void operator()(
const std::vector<segmentation::token_pos>& tokens, uint32_t len) = 0;
76template <
typename TaggingAuxScalar=
float>
84 const std::vector<StringIndex::idx_t> m_lemm_buffer;
85 std::shared_ptr< StdMatrix<uint8_t> > m_classes;
92 const std::vector<StringIndex::idx_t>& lemm_buffer,
94 : m_stridx(stridx), m_buffer(buffer), m_lemm_buffer(lemm_buffer), m_classes(classes),
95 m_current(0), m_offset(offset), m_end(
end - offset)
97 assert(
end >= offset + 1);
102 return m_current >= m_end;
108 return m_buffer[m_current].m_flags;
113 return m_buffer[m_current].m_offset;
118 return m_buffer[m_current].m_len;
125 return m_buffer[m_current].m_mwt_len;
130 return m_stridx.
get_str(m_buffer[m_current].m_mwt_surface_idx).c_str();
137 return m_buffer[m_current].m_mwt_surface_idx;
142 return m_buffer[m_current].m_form_idx;
147 return m_lemm_buffer[m_current];
150 inline const char*
form()
const
153 const std::string& f = m_stridx.
get_str(m_buffer[m_current].m_form_idx);
160 const std::string& f = m_stridx.
get_str(m_lemm_buffer[m_current]);
166 throw std::runtime_error(
"TokenSequenceAnalyzer<T> does not implement head");
197 uint8_t val = m_classes->get(m_current + m_offset, cls_idx);
237 inline const std::string&
form()
const
254 : m_data(data), m_token(stridx) { }
258 return m_data.size();
304 const std::string& lemm_model_fn,
305 const std::string& lemm_dict_fn,
306 const std::string& fixed_ini_fn,
307 const std::string& lower_ini_fn,
308 const std::string& fixed_lemm_fn,
326 assert(num_buffers > 0);
332 m_cls.load(model_fn, path_resolver);
337 std::fill(b.begin(), b.end(),
m_unk_idx);
341 for (uint32_t i = 0; i < buff.size(); ++i)
343 buff[i].m_form_idx = i;
349 if (lemm_model_fn.size() > 0)
355 catch (
const std::runtime_error& e)
357 std::cerr <<
"TokenSequenceAnalyzer failed to load lemmatization model " << lemm_model_fn << std::endl;
363 m_cls.register_handler([
this](
365 size_t begin,
size_t end,
size_t slot_idx){
382 m_cls.register_handler([
this](
384 size_t begin,
size_t end,
size_t slot_idx)
399 if (lemm_dict_fn.size() > 0)
403 if (fixed_ini_fn.size() > 0)
407 if (lower_ini_fn.size() > 0)
411 if (fixed_lemm_fn.size() > 0)
418 std::vector<std::string>& classes_names,
419 std::vector<std::vector<std::string>>& classes)
421 m_cls.get_classes_from_fn(fn, classes_names, classes);
434 virtual const std::vector<std::vector<std::string>>&
get_classes()
const override
436 return m_cls.get_output_str_dicts();
441 return m_cls.get_output_str_dicts_names();
444 virtual std::shared_ptr<StringIndex>
get_stridx()
const override
471 m_cls.send_all_results();
478 virtual void operator()(
const std::vector<deeplima::segmentation::token_pos>& tokens, uint32_t len)
override
485 for (
size_t i = 0; i < len; i++)
526 while (next_buffer.
locked())
528 m_cls.send_next_results();
530 assert(!next_buffer.
locked());
556 return std::hash<StringIndex::idx_t>()(arg.first) ^ arg.second.hash();
563 std::ifstream f(fn, std::ios::in);
565 std::cerr <<
"load_lemm_cache failed to open file " << fn <<
".\n";
566 throw std::runtime_error(std::string(
"load_lemm_cache failed to open file ") + fn);
569 while (std::getline(f, line))
571 if (line.size() == 0)
575 const std::vector<std::string> v =
utils::split(line,
'\t');
578 throw std::runtime_error(std::string(
"Can't decode dict line \"") + line +
"\"");
581 const std::vector<std::string> upos_feats =
utils::split(v[1],
' ');
582 if (upos_feats.size() != 2)
584 throw std::runtime_error(std::string(
"Can't decode upos and feats in dict line \"") + line +
"\"");
587 std::map<std::string, std::set<std::string>> feats;
590 throw std::runtime_error(std::string(
"Can't parse feats in dict line \"") + line +
"\"");
602 throw std::runtime_error(std::string(
"Duplicate keys in dict: \"") + line +
"\"");
617 std::unordered_set<morph_model::morph_feats_t>
load_pos_cache(
const std::string& fn)
619 std::unordered_set<morph_model::morph_feats_t> result;
621 std::ifstream f(fn, std::ios::in);
623 std::cerr <<
"load_pos_cache failed to open file " << fn <<
".\n";
624 throw std::runtime_error(std::string(
"load_pos_cache failed to open file ") + fn);
627 while (std::getline(f, line))
629 if (line.size() == 0 || line[0] ==
'#')
634 std::map<std::string, std::set<std::string>> feats;
637 result.insert(encoded_feats);
646 inline static std::u32string
to_lower(
const std::u32string& src)
648 std::u32string copy = src;
649 std::transform(copy.begin(), copy.end(), copy.begin(),
650 [](
unsigned char c){ return std::tolower(c); });
678 std::vector<StringIndex::idx_t>& lemm_buffer,
680 size_t offset,
size_t end)
682 std::u32string target;
684 for (
size_t i = 0; i < end - offset; ++i)
686 bool sentence_begin = (i==0 || buffer[i-1].eos());
691 lemm_buffer[i] = buffer[i].m_form_idx;
703 lemm_buffer[i] = buffer[i].m_form_idx;
716 lemm_buffer[i] = buffer[i].m_form_idx;
731 lemm_buffer[i] = target.empty() ? buffer[i].m_form_idx
739 lemm_buffer[i] = it->second;
760 std::unordered_map<lemm_cache_key_t, StringIndex::idx_t, lemm_cache_key_hash>
m_lemm_cache;
static bool parse_feats(const std::string &s, std::map< std::string, std::set< std::string > > &_feats)
Handle multithread processing of token sequence.
std::function< void(std::shared_ptr< StringIndex > stridx, const token_buffer_t<> &tokens, const std::vector< StringIndex::idx_t > &lemmata, std::shared_ptr< StdMatrix< uint8_t > > classes, size_t begin, size_t end) > output_callback_t
virtual void finalize()=0
virtual void register_handler(const output_callback_t fn)=0
virtual std::shared_ptr< StringIndex > get_stridx() const =0
virtual const std::vector< std::vector< std::string > > & get_classes() const =0
virtual void operator()(const std::vector< segmentation::token_pos > &tokens, uint32_t len)=0
virtual const std::vector< std::string > & get_class_names() const =0
const S & get_str(const idx_t idx) const
idx_t get_idx(const char *p, size_t len)
const U & get_ustr(const idx_t idx)
accessor with side effect.
TokenIterator(const StringIndex &stridx, const token_buffer_t<> &buffer, const std::vector< StringIndex::idx_t > &lemm_buffer, std::shared_ptr< StdMatrix< uint8_t > > classes, size_t offset, size_t end)
uint32_t form_idx() const
uint32_t lemma_idx() const
const char * form() const
const char * deprel() const
const char * mwt_surface() const
uint16_t token_len() const
uint16_t token_offset() const
uint32_t mwt_surface_idx() const
token_flags_t flags() const
uint8_t token_class(size_t cls_idx) const
const char * lemma() const
void reset(size_t position=0)
const enriched_token_t & operator[](size_t idx) const
enriched_token_buffer_t(const token_buffer_t<> &data, const StringIndex &stridx)
token_buffer_t ::size_type size() const
enriched_token_t(const StringIndex &stridx)
const StringIndex & m_stridx
void set_token(const token_buffer_t<>::token_t *p)
const std::string & form() const
const token_buffer_t ::token_t * m_ptoken
token_flags_t flags() const
StringIndex::idx_t m_unk_idx
void start_analysis(size_t buffer_idx, int count=-1)
std::unordered_set< morph_model::morph_feats_t > m_fixed_lemm_cache
std::vector< token_buffer_t<> > m_buffers
std::unordered_map< lemm_cache_key_t, StringIndex::idx_t, lemm_cache_key_hash > m_lemm_cache
std::unordered_set< morph_model::morph_feats_t > m_lower_ini_cache
TokenSequenceAnalyzer(const std::string &model_fn, const std::string &lemm_model_fn, const std::string &lemm_dict_fn, const std::string &fixed_ini_fn, const std::string &lower_ini_fn, const std::string &fixed_lemm_fn, const PathResolver &path_resolver, size_t buffer_size, size_t num_buffers)
std::pair< StringIndex::idx_t, morph_model::morph_feats_t > lemm_cache_key_t
lemmatization::impl::LemmatizationImpl m_lemm
virtual const std::vector< std::vector< std::string > > & get_classes() const override
tagging::impl::TaggingImpl< TaggingAuxScalar > m_cls
virtual void finalize() override
static std::u32string to_lower(const std::u32string &src)
This well lower onlu Latin1 characters.
TokenIterator output_iterator_t
std::vector< std::vector< StringIndex::idx_t > > m_lemm_buffers
size_t m_current_timepoint
virtual void register_handler(const output_callback_t fn) override
output_callback_t m_output_callback
virtual const std::vector< std::string > & get_class_names() const override
std::unordered_set< morph_model::morph_feats_t > load_pos_cache(const std::string &fn)
void get_classes_from_fn(const std::string &fn, std::vector< std::string > &classes_names, std::vector< std::vector< std::string > > &classes)
void process_buffer(size_t buffer_idx)
std::shared_ptr< StringIndex > m_stridx_ptr
virtual void operator()(const std::vector< deeplima::segmentation::token_pos > &tokens, uint32_t len) override
void load_lemm_cache(const std::string &fn)
std::shared_ptr< StdMatrix< uint8_t > > m_classes
virtual std::shared_ptr< StringIndex > get_stridx() const override
void lemmatize(const token_buffer_t<> &buffer, std::vector< StringIndex::idx_t > &lemm_buffer, std::shared_ptr< StdMatrix< uint8_t > > classes, size_t offset, size_t end)
TODO correct this function.
std::unordered_set< morph_model::morph_feats_t > m_fixed_ini_cache
virtual ~TokenSequenceAnalyzer()
const morph_model::morph_model_t & get_morph_model() const
bool is_fixed(std::shared_ptr< StdMatrix< uint8_t > > classes, size_t idx)
void init(size_t max_input_word_len, const std::vector< std::string > &class_names, const std::vector< std::vector< std::string > > &class_values)
void predict(const std::u32string &form, std::shared_ptr< StdMatrix< uint8_t > > classes, size_t idx, std::u32string &target)
morph_model::morph_feats_t get_morph_feats(std::shared_ptr< StdMatrix< uint8_t > > classes, size_t idx) const
virtual void load(const std::string &fn, const PathResolver &)
Encoding on one 64 bits integer of the set of morphological features for one token.
Helper class for morphology data (upos, features) binarization.
morph_feats_t convert(const std::string &upos, const std::map< std::string, std::set< std::string > > &feats) const
Class implementing the tagger, used as member in TokenSequenceAnalyzer, the main tagger class Son of ...
std::vector< std::string > split(const std::string &str, char delim)
std::size_t operator()(const lemm_cache_key_t &arg) const
uint32_t m_mwt_surface_idx
const char * m_mwt_surface_pch
uint16_t m_mwt_surface_len
std::size_t operator()(deeplima::morph_model::morph_feats_t const &s) const noexcept