TkN 2.1
Toolkit for Nuclei
tkelement_builder.cpp
1/********************************************************************************
2 * Copyright (c) : Université de Lyon 1, CNRS/IN2P3, UMR5822, *
3 * IP2I, F-69622 Villeurbanne Cedex, France *
4 * Normandie Université, ENSICAEN, UNICAEN, CNRS/IN2P3, *
5 * LPC Caen, F-14000 Caen, France *
6 * Contibutor(s) : *
7 * Jérémie Dudouet jeremie.dudouet@cnrs.fr [2020] *
8 * Diego Gruyer diego.gruyer@cnrs.fr [2020] *
9 * *
10 * This software is governed by the CeCILL-B license under French law and *
11 * abiding by the rules of distribution of free software. You can use, *
12 * modify and/ or redistribute the software under the terms of the *
13 * CeCILL-B license as circulated by CEA, CNRS and INRIA at the following *
14 * URL \"http://www.cecill.info\". *
15 * *
16 * As a counterpart to the access to the source code and rights to copy, *
17 * modify and redistribute granted by the license, users are provided *
18 * only with a limited warranty and the software's author, the holder of *
19 * the economic rights, and the successive licensors have only limited *
20 * liability. *
21 * *
22 * In this respect, the user's attention is drawn to the risks associated *
23 * with loading, using, modifying and/or developing or reproducing the *
24 * software by the user in light of its specific status of free software, *
25 * that may mean that it is complicated to manipulate, and that also *
26 * therefore means that it is reserved for developers and experienced *
27 * professionals having in-depth computer knowledge. Users are therefore *
28 * encouraged to load and test the software's suitability as regards *
29 * their requirements in conditions enabling the security of their *
30 * systems and/or data to be ensured and, more generally, to use and *
31 * operate it in the same conditions as regards security. *
32 * *
33 * The fact that you are presently reading this means that you have had *
34 * knowledge of the CeCILL-B license and that you accept its terms. *
35 ********************************************************************************/
36
37#include "tkelement_builder.h"
38
39#include <fstream>
40
41#include "tklog.h"
42#include "json.hpp"
43
44namespace tkn {
51}
52
53using namespace tkn;
54using namespace std;
55using json = nlohmann::json;
56
57tkelement_builder::tkelement_builder(tkdatabase *_database, const char *_table_name) : fDataBase(_database), fTableName(_table_name)
58{
59}
60
62
63int tkelement_builder::fill_database(const char *_atomic_db, const char* _xrays_db, int _only_charge)
64{
65 glog.set_class("db_element_builder");
66 glog.set_method(tkstring::form("fill_database('%s')",_atomic_db));
67
68 gdebug << "calling tkelement_builder::fill_database(...)" << do_endl;
69
70 tkdb_table &fTable = fDataBase->new_table(fTableName);
71 read_atomic_db(_atomic_db);
72 read_xrays_db(_xrays_db);
73
74 // table initialisation
75
76 char * sErrMsg = nullptr;
77
78 fTable.add_column("element_id","INT PRIMARY KEY NOT NULL");
79
80 for(auto &idx: indexes) {
81 tkstring name = columns.at(idx);
82 tkstring type = types.at(idx);
83 fTable.add_column(name.data(),type.data());
84 if(units.at(idx) != "None") {
85 name += "_unit";
86 fTable.add_column(name.data(),"TEXT");
87 }
88 }
89 for(auto &xray: fxrays_possible_names) {
90 fTable.add_column(xray.data(),"FLOAT");
91 }
92 fTable.write_to_database();
93
94 // filling the database
95 int idx = 1;
96 for(auto &elt: fmap_of_atomic_properties) {
97 tkstring message = "Building '" + fTable.get_name() + "' table";
98 glog.progress_bar(fmap_of_atomic_properties.size(),idx,message.data());
99
100// fTable["element_id"].set_value(idx++);
101 int current_charge = get<2>(elt.second.at("charge")).atoi();
102 fTable["element_id"].set_value(current_charge+1);
103 tkstring element_symbol = get<2>(elt.second.at("symbol"));
104 if(element_symbol == "n") element_symbol = "neutron";
105
106 for(auto &prop : elt.second) {
107 tkstring name = get<0>(prop.second);
108 tkstring unit = get<1>(prop.second);
109 tkstring value = get<2>(prop.second);
110 tkstring type = get<3>(prop.second);
111
112 if(type.contains("INT")) fTable[name.data()].set_value(value.atoi());
113 else if(type.contains("TEXT")) fTable[name.data()].set_value(value.data());
114 else if(type.contains("FLOAT")) fTable[name.data()].set_value(value.atof());
115 if(unit !="None") fTable[tkstring::form("%s_unit",name.data())].set_value(unit.data());
116 }
117 if(fmap_of_xrays.count(current_charge)) {
118 for(auto &xray: fmap_of_xrays.at(current_charge)) {
119 tkstring name, unit; double value;
120 std::tie(name, unit, value) = xray;
121 fTable[name.data()].set_value(value);
122 }
123 }
124 bool do_push = (_only_charge==0 || _only_charge==current_charge);
125 if(do_push) {
126 fTable.push_row();
127 fDataBase->exec_sql(tkstring::form("CREATE VIEW elt%s as select * from element where element.charge=%d",element_symbol.data(),current_charge));
128 }
129 }
130
131 sqlite3_exec(fDataBase->get_sql_db(), "END TRANSACTION", nullptr, nullptr, &sErrMsg);
132 fDataBase->exec_sql("CREATE INDEX charge_index ON element(charge)");
133
134 glog.clear();
135
136 return 0;
137}
138
139void tkelement_builder::read_atomic_db(const char *_atomic_db) {
140
141 gdebug << "filling atomic database using : " << _atomic_db << do_endl;
142
143 std::ifstream f_in;
144 f_in.open(_atomic_db);
145 json jf = json::parse(f_in);
146
147
148
149 auto &table = jf.at("Table");
150
151 for(auto &entry: table.items()) {
152 if(entry.key()=="Columns") {
153 for(auto &col: entry.value().at("Column").items()) {
154 columns.push_back(col.value());
155 if(col.value()=="CPKHexColor") continue;
156 if(col.value()=="electronegativity") continue;
157 if(col.value()=="electron_affinity") continue;
158 if(col.value()=="oxidation_states") continue;
159
160 indexes.push_back(tkstring(col.key()).atoi());
161 }
162 }
163 else if(entry.key()=="Columns_Units") {
164 for(auto &col: entry.value().at("Column").items()) {
165 units.push_back(col.value());
166 }
167 }
168 else if(entry.key()=="Columns_Types") {
169 for(auto &col: entry.value().at("Column").items()) {
170 types.push_back(col.value());
171 }
172 }
173 else if(entry.key()=="Row") {
174 for(auto &elt: entry.value().items()) {
175 auto col = elt.value().at("Cell");
176 int atomic_number = col.at(0).get<tkstring>().atoi();
177 map<tkstring,atomic_properties> properties;
178 for(auto &i: indexes) {
179 if(col.at(i).get<tkstring>().length()==0) continue;
180 properties.insert({columns.at(i),{columns.at(i),units.at(i),col.at(i).get<tkstring>(),types.at(i)}});
181 }
182 fmap_of_atomic_properties.insert({atomic_number,properties});
183 }
184 }
185 }
186
187 // for(auto &elt: fmap_of_atomic_properties) {
188 // glog << info <<"New element: " << get<2>(elt.second.at("name")) << do_endl;
189 // for(auto &prop : elt.second) {
190 // cout << left << setw(40) << prop.first << " = " << get<2>(prop.second);
191 // if(get<1>(prop.second) != "None") cout << " " << get<1>(prop.second);
192 // cout<<endl;
193 // }
194 // }
195}
196
197void tkelement_builder::read_xrays_db(const char *_xrays_db) {
198
199 std::ifstream f_in;
200 f_in.open(_xrays_db);
201
202 json jf = json::parse(f_in);
203
204 auto &table = jf.at("Elements");
205
206 for(auto &entry: table.items()) {
207 auto Z = entry.value().at("Z");
208 auto name = entry.value().at("name");
209 auto xrays = entry.value().at("Xrays");
210
211 vector<atomic_xray> atom_xrays;
212 for(auto &xray: xrays) {
213 tkstring name = xray.at("name").get<tkstring>();
214 name.prepend("XRay_");
215 tkstring unit = xray.at("unit").get<tkstring>();
216 double value = xray.at("value").get<double>()/1000.;
217 atom_xrays.emplace_back(name,unit,value);
218 if(!fxrays_possible_names.count(name)) fxrays_possible_names.insert(name);
219 }
220 if(!atom_xrays.empty()) fmap_of_xrays.insert({Z,atom_xrays});
221 }
222
223// tkstring name, unit;
224// double value;
225// for(auto &elt: fmap_of_xrays) {
226// cout << elt.first << " " << endl;
227// for(auto &xray: elt.second) {
228// std::tie(name, unit, value) = xray;
229// cout << " -- " << setw(10) << name << " : " << setw(10) << value << " " << unit << endl;
230// }
231// }
232}
233
234#ifdef HAS_ROOT
235ClassImp(tkelement_builder);
236#endif
Interface to the sqlite database.
Definition: tkdatabase.h:57
tkdb_table & new_table(tkstring _table_name)
Definition: tkdatabase.cpp:187
int exec_sql(const char *_cmd)
returns the first value for selection
Definition: tkdatabase.cpp:327
sqlite3 * get_sql_db()
Definition: tkdatabase.h:84
Representaiton of a sqlite data table.
Definition: tkdb_table.h:52
tkstring get_name()
Definition: tkdb_table.h:116
void write_to_database()
Definition: tkdb_table.cpp:265
void add_column(const char *_colname, const char *_coltype)
Definition: tkdb_table.cpp:195
Decoding of the element properties.
virtual ~tkelement_builder()
int fill_database(const char *_atomic_db, const char *_xrays_db, int _only_charge=0)
std::string with usefull tricks from TString (ROOT) and KVString (KaliVeda) and more....
Definition: tkstring.h:54
static const char * form(const char *_format,...)
Definition: tkstring.cpp:431
int atoi() const
Converts a string to integer value.
Definition: tkstring.cpp:175
bool contains(const char *_pat, ECaseCompare _cmp=kExact) const
Definition: tkstring.h:197
tkstring & prepend(const tkstring &_st)
Definition: tkstring.h:224
double atof() const
Converts a string to double value.
Definition: tkstring.cpp:191
Definition: tklog.cpp:39
std::map< tkstring, pair< tkstring, tkstring > > properties
Definition: tkmeasure.h:57
tklog & do_endl(tklog &log)
Definition: tklog.h:235