Medial Code Documentation
Loading...
Searching...
No Matches
MedDictionary.h
1//
2// MedDictionary.h - classes for dictionary and sets handling
3//
4
5#ifndef __MED__DICTIONARY__H__
6#define __MED__DICTIONARY__H__
7
8#include <string>
9#include <vector>
10#include <map>
11#include <nlohmann/json.hpp>
12
13using namespace std;
14using json = nlohmann::json;
15
16//#define MAX_DICT_ID_NUM 10000000
17
18class DLLEXTERN MedDictionary {
19
20public:
21 vector<string> fnames;
22 map<string, int> Name2Id; // we allow several names for each Id, the first one read will be the "official" name
23 map<int, string> Id2Name; // from an id to the "official" name
24 map<int, string> Id2LongestName; // from an id to its most "comprehensive" name
25 map<int, vector<string>> Id2Names; // a list of all the names given to an id.
26 map<pair<int, int>, int> MemberInSet; // pair.first = set number, pair second = member number
27 map<int, vector<int>> Set2Members; // for each set a vector of all members of that set
28 map<int, vector<int>> Member2Sets; // for each id - a vector of all sets the id is a member of
29 int dict_id; // for debug
30 unordered_set<string> section_name; // for debug and for checking if a signal related to this dictionary
31
32 void clear() { fnames.clear(); Name2Id.clear(); MemberInSet.clear(); Set2Members.clear(); }
33 int read(const string &fname);
34 int read(vector<string> &dfnames);
35 int read(string path, vector<string> &dfnames);
36 int id(const string &name) const;
37 int id_list(vector<string> &names, vector<int> &ids);
38 string name(int id);
39
40 int is_in_set(int member_id, int set_id);
41 int is_in_set(const string& member, const string& set_name);
42 int is_in_set(int member_id, const string &set_name);
43 int is_in_set(const string& member, int set_id);
44
45 int prep_sets_lookup_table(const vector<string> &set_names, vector<char> &lut) const;
46 int prep_sets_indexed_lookup_table(const vector<string> &set_names, vector<unsigned char> &lut);
47
48 void get_set_members(const string &set, vector<int> &members);
49 void get_set_members(int set_id, vector<int> &members);
50 void get_member_sets(const string &member, vector<int> &sets);
51 void get_member_sets(int member_id, vector<int> &sets);
52
53 // next function calculates for each member ALL the sets it is contained in , applying all set transitivity
54 void get_members_to_all_sets(vector<int> &members, unordered_map<int, vector<int>> &Member2AllSets);
55 void get_members_to_all_sets(vector<int> &members, vector<int> &sets, unordered_map<int, vector<int>> &Member2AllSets);
56
57 void get_regex_ids(string regex_s, vector<int> &ids);
58 void get_regex_names(string regex_s, vector<string> &names);
59
60 int add_def(const string &fname, const string &name, int id);
61 int add_set(const string &fname, const string &member_name, const string &set_name);
62
63 // APIs to push new values into a dictionary
64 void push_new_def(string name, int id); // { Name2Id[name] = id; Id2Name[id] = name; Id2Names[id].push_back(name); }
65 void push_new_set(int set_id, int member_id);
66
67
68
69 // write to file : mode=1: only defs, mode=2: defs+sets
70 int write_to_file(string fout, int mode = 1);
71
72private:
73 map<string, int> used;
74
75};
76
77//
78// next class is a natural expansion of the dictionary class
79// There are several "namespaces" or sections of dictionaries.
80// The main one is the "DEFAULT" section, which always holds the signal ids (at least)
81// Each dictionary file can be assigned to a section using the SECTION <name> statement in its first line (can be in one of the 100 first lines to make it easier)
82// Each section has its OWN coding system, and hence can use values used in other sections.
83// When using a dictionary, using it as done up to now (rep.dict.id()) will simply use the DEFAULT section.
84// When we want to use a section we can use an API that has also the section name as input (better call section names with the name of the signal used)
85// We can also set a certain section as the default section (and reset back to "DEFAULT")
86//
87
88class DLLEXTERN MedDictionarySections {
89
90 //class MedDictionarySections {
91
92public:
93 vector<string> sections_names; // [0] is always "DEFAULT"
94 vector<vector<string>> section_fnames;
95 vector<MedDictionary> dicts;
96 map<string, int> SectionName2Id;
97 int default_section;
98 int curr_section;
99 int read_state;
100
101 // clearing
102 void clear() { sections_names.clear(); section_fnames.clear(); dicts.clear(); SectionName2Id.clear(); default_section = 0; curr_section = 0; init(); }
103
104 // set curr/default
105 int set_curr_dict(int id) { curr_section = id; return 0; }
106 int set_curr_dict(const string name) { curr_section = SectionName2Id[name]; return 0; }
107 int reset() { curr_section = default_section; return 0; }
108
109 // initializations
110 void init() {
111 sections_names.push_back("DEFAULT"); section_fnames.push_back(vector<string>());
112 dicts.resize(1); SectionName2Id["DEFAULT"] = 0;
113 default_section = 0; curr_section = 0; read_state = 0;
114 }
115 MedDictionarySections() { init(); }
116 int read(const string &fname);
117 int read(vector<string> &dfnames);
118 int read(string path, vector<string> &dfnames);
119
120
121 // in the following calls note that WE DO NOT CHECK IF section_id or section_name exist and appear in the map and correct range.
122 // this is done for efficiency (saving an if for each call).
123
124 // get a pointer to relevant dictionary
125 MedDictionary *curr_dict() { return &dicts[curr_section]; }
126 MedDictionary *dict(int section_id) { return &dicts[section_id]; }
127
128 int section_id(const string &name) { if (SectionName2Id.find(name) == SectionName2Id.end()) return 0; else return SectionName2Id[name]; }
129
130 // use MedDictionary functions for a specific section id
131 int id(int section_id, const string &name) { return dicts[section_id].id(name); }
132 int get_id_or_throw(int section_id, const string &name) { int v = dicts[section_id].id(name); if (v < 0) throw invalid_argument(name); else return v; }
133 int id_list(int section_id, vector<string> &names, vector<int> &ids) { return dicts[section_id].id_list(names, ids); }
134 string name(int section_id, int id) { return dicts[section_id].name(id); }
135
136 int is_in_set(int section_id, int member_id, int set_id) { return dicts[section_id].is_in_set(member_id, set_id); }
137 int is_in_set(int section_id, const string& member, const string& set_name) { return dicts[section_id].is_in_set(member, set_name); }
138 int is_in_set(int section_id, int member_id, const string &set_name) { return dicts[section_id].is_in_set(member_id, set_name); }
139 int is_in_set(int section_id, const string& member, int set_id) { return dicts[section_id].is_in_set(member, set_id); }
140
141 void get_set_members(int section_id, const string &set, vector<int> &members) { return dicts[section_id].get_set_members(set, members); }
142 void get_set_members(int section_id, int set_id, vector<int> &members) { return dicts[section_id].get_set_members(set_id, members); }
143 void get_member_sets(int section_id, const string &member, vector<int> &sets) { return dicts[section_id].get_member_sets(member, sets); }
144 void get_member_sets(int section_id, int member_id, vector<int> &sets) { return dicts[section_id].get_member_sets(member_id, sets); }
145
146 // use curr_dict (typically default one)
147 int id(const string &name) { return id(curr_section, name); }
148 int id_list(vector<string> &names, vector<int> &ids) { return id_list(curr_section, names, ids); }
149 string name(int id) { return name(curr_section, id); }
150
151 int is_in_set(int member_id, int set_id) { return is_in_set(curr_section, member_id, set_id); }
152 int is_in_set(const string& member, const string& set_name) { return is_in_set(curr_section, member, set_name); }
153 int is_in_set(int member_id, const string &set_name) { return is_in_set(curr_section, member_id, set_name); }
154 int is_in_set(const string& member, int set_id) { return is_in_set(curr_section, member, set_id); }
155
156 void get_set_members(const string &set, vector<int> &members) { return get_set_members(curr_section, set, members); }
157 void get_set_members(int set_id, vector<int> &members) { return get_set_members(curr_section, set_id, members); }
158 void get_member_sets(const string &member, vector<int> &sets) { return get_member_sets(curr_section, member, sets); }
159 void get_member_sets(int member_id, vector<int> &sets) { return get_member_sets(curr_section, member_id, sets); }
160
161 // APIs to prepare lookup tables
162 int prep_sets_lookup_table(int section_id, const vector<string> &set_names, vector<char> &lut) { return dicts[section_id].prep_sets_lookup_table(set_names, lut); }
163 int prep_sets_indexed_lookup_table(int section_id, const vector<string> &set_names, vector<unsigned char> &lut) { return dicts[section_id].prep_sets_indexed_lookup_table(set_names, lut); }
164
165 // APIs to add a new dictionary section - this is needed in some cases of creating virtual signals that are categorial
166 void add_section(string new_section_name); // { MedDictionary dummy; dicts.push_back(dummy); SectionName2Id[new_section_name] = (int)dicts.size() - 1; }
167 void connect_to_section(string new_section_name, int section_id); // { SectionName2Id[new_section_name] = section_id; }
168
169 // push new defs/sets from a json object:
170 // new elements get an automatic new id.
171 // sets: elements must already be defined.
172 int add_json(json &js); // auto detects the format
173 int add_json_simple_format(json &js);
174
175};
176
177
178#endif
Definition MedDictionary.h:88
Definition MedDictionary.h:18