37#include "tkisotope_builder.h"
74tkisotope_builder::tkisotope_builder(
tkdatabase *_database,
const char *_table_name) :
tkdb_builder(_database, _table_name)
76 fTable = &fDataBase->new_table(fTableName);
78 fTable->add_column(
"isotope_id",
"INT PRIMARY KEY NOT NULL");
79 fTable->add_column(
"element_id",
"INT NOT NULL");
80 fTable->add_column(
"mass",
"INT");
84 fTable->add_column(
"isotope_year_discovered",
"INT");
86 add_measure(
"mass_excess",
false);
87 add_measure(
"electric_quadrupole",
false);
88 add_measure(
"magnetic_dipole",
false);
89 add_measure(
"radius",
false);
93 add_measure(
"abundance",
false);
94 add_measure(
"quadrupoleDeformation",
false);
96 add_measure(
"FY235U",
false);
97 add_measure(
"FY238U",
false);
98 add_measure(
"FY239Pu",
false);
99 add_measure(
"FY241Pu",
false);
100 add_measure(
"FY252Cf",
false);
102 add_measure(
"cFY235U",
false);
103 add_measure(
"cFY238U",
false);
104 add_measure(
"cFY239Pu",
false);
105 add_measure(
"cFY241Pu",
false);
106 add_measure(
"cFY252Cf",
false);
108 fTable->add_column(
"decay_modes",
"TEXT");
112 fTable->add_column(
"spin",
"REAL");
113 fTable->add_column(
"parity",
"INT");
114 fTable->add_column(
"spin_parity",
"TEXT");
116 add_measure(
"lifetime",
false);
118 fTable->add_constraint(
"FOREIGN KEY (element_id) REFERENCES ELEMENT (element_id)");
119 fTable->write_to_database();
121 glog <<
info <<
"Creating '" << _table_name <<
"' table" <<
do_endl;
126void tkisotope_builder::fill_isotope(
const json_nucleus &_json_nuc)
132 (*fTable)[
"isotope_id"].set_value(fIsotopeIdx);
133 (*fTable)[
"element_id"].set_value(_json_nuc.Z+1);
134 (*fTable)[
"mass"].set_value(_json_nuc.A);
135 (*fTable)[
"isotope_year_discovered"].set_value(_json_nuc.year);
137 fill_measure(
"mass_excess",_json_nuc.mass_excess,
false);
138 fill_measure(
"abundance",_json_nuc.abundance,
false);
139 fill_measure(
"quadrupoleDeformation",_json_nuc.quadrupoleDeformation,
false);
141 fill_measure(
"FY235U",_json_nuc.FY235U,
false);
142 fill_measure(
"FY238U",_json_nuc.FY235U,
false);
143 fill_measure(
"FY239Pu",_json_nuc.FY239Pu,
false);
144 fill_measure(
"FY241Pu",_json_nuc.FY239Pu,
false);
145 fill_measure(
"FY252Cf",_json_nuc.FY252Cf,
false);
147 fill_measure(
"cFY235U",_json_nuc.cFY235U,
false);
148 fill_measure(
"cFY238U",_json_nuc.cFY235U,
false);
149 fill_measure(
"cFY239Pu",_json_nuc.cFY239Pu,
false);
150 fill_measure(
"cFY241Pu",_json_nuc.cFY239Pu,
false);
151 fill_measure(
"cFY252Cf",_json_nuc.cFY252Cf,
false);
153 fill_measure(
"electric_quadrupole",_json_nuc.electric_quadrupole,
false);
154 fill_measure(
"magnetic_dipole",_json_nuc.magnetic_dipole,
false);
155 fill_measure(
"radius",_json_nuc.radius,
false);
158 if(_json_nuc.Z==0 && _json_nuc.N ==1) {
160 lifetime.
value = 613.9;
164 fill_measure(
"lifetime",lifetime,
false);
168 for(
auto &dec: _json_nuc.decay_modes) decays.
append(
tkstring::form(
"[%s;%g]",dec.first.data(),dec.second));
169 (*fTable)[
"decay_modes"].set_value(decays.data());
176 glog.set_class(
"db_isotope_builder");
177 glog.set_method(
tkstring::form(
"fill_database('%s','%s')",_json_filename,_gs_filename));
179 tkdb_table &fTable = (*fDataBase)[fTableName.data()];
183 std::ifstream ifs(_json_filename);
190 json jf = json::parse(ifs);
192 auto &nuclides = jf.at(
"nuclides");
193 int NNucs = nuclides.size();
196 map<int, map<int, json_nucleus>> nuclei;
199 for(
auto &nuc: nuclides) {
200 json_nucleus json_nuc = read_nucleus(nuc);
202 bool do_push = ((_only_charge==0) && (_only_mass==0));
203 if((_only_charge == json_nuc.Z) && (_only_mass == 0)) do_push =
true;
204 if((_only_charge == json_nuc.Z) && (_only_mass == json_nuc.A)) do_push =
true;
205 if((_only_charge == 0) && (_only_mass == json_nuc.A)) do_push =
true;
208 nuclei[json_nuc.Z][json_nuc.A] = json_nuc;
211 glog.progress_bar(NNucs,inuc,message.data());
215 std::map<int,tkn::tkstring> columns;
218 fstream file (_gs_filename, ios::in);
222 if(!getline(file,line))
return 1;
224 for(
const auto &cname : line.
tokenize(
",")) columns[ic++] = cname;
227 while(getline(file, line))
229 std::map<tkn::tkstring, tkn::tkstring> values;
233 for(
auto val : line.
tokenize(
",")) {val.
remove_all(
" "); values[columns[ic]] = val; ic++;}
236 if(!nread.
contains(
tkstring::form(
"(%d,%d)",values[
"z"].atoi(),values[
"n"].atoi()+values[
"z"].atoi())))
continue;
237 auto& nuc = nuclei[values[
"z"].atoi()][values[
"n"].atoi()+values[
"z"].atoi()];
238 if(!values[
"massexcess"].is_empty()) nuc.mass_excess = {values[
"massexcess"].atof(),values[
"unc_me"].atof(),-1.,-1.,
"keV",values[
"me_systematics"].equal_to(
"Y")?
";ERR=SY":
"",
true};
239 if(!values[
"radius"].is_empty())nuc.radius = {values[
"radius"].atof(),values[
"unc_r"].atof(),-1.,-1.,
"fm",
"",
true};
240 if(!values[
"electric_quadrupole"].is_empty()) nuc.electric_quadrupole = {values[
"electric_quadrupole"].atof(),values[
"unc_eq"].atof(),-1.,-1.,
"barn",
"",
true};
241 if(!values[
"magnetic_dipole"].is_empty()) nuc.magnetic_dipole = {values[
"magnetic_dipole"].atof(),values[
"unc_md"].atof(),-1.,-1.,
"mun",
"",
true};
242 if(!values[
"discovery"].is_empty()) nuc.year = values[
"discovery"].atoi();
246 fDataBase->exec_sql(
"BEGIN TRANSACTION");
249 for(
auto &z: nuclei) {
250 for(
auto &a: z.second) {
253 fill_isotope(a.second);
255 fDataBase->exec_sql(
tkstring::form(
"CREATE VIEW nuc%s as select * from isotope INNER JOIN element on isotope.element_id=element.element_id where element.charge=%d AND isotope.mass=%d",a.second.name.data(),a.second.Z,a.second.A));
256 glog.progress_bar(NNucs,inuc,message.data());
261 fDataBase->exec_sql(
"END TRANSACTION");
263 fDataBase->exec_sql(
"CREATE INDEX element_index ON isotope(element_id)");
264 fDataBase->exec_sql(
"CREATE INDEX mass_index ON isotope(mass)");
274 for(
auto &_item: entry.items()) {
275 const auto &_key = _item.key();
276 const auto &_val = _item.value();
277 if(_key ==
"formats")
continue;
278 if(_key ==
"uncertainty") _data.
err = _val.get<
tkstring>().atof();
279 else if(_key ==
"value") _data.
value = _val.get<
tkstring>().atof();
280 else if(_key ==
"unit") _data.
unit = _val.get<
tkstring>();
281 else if(_key ==
"isSystematics" && _val ==
"true") _data.
info.
append(
";ERR=SY");
283 glog <<
error << key <<
": unkown key: " << _key <<
" type: "<< _item.value().type_name() <<
do_endl;
284 cout << _val << endl;
292 if(tokens.size()==2) {
293 _data.
err = tokens.back().
atof();
299tkisotope_builder::json_nucleus tkisotope_builder::read_nucleus(json &entry) {
302 for(
auto &item: entry.items())
304 auto &key = item.key();
305 auto &val = item.value();
306 if(key ==
"name") nuc.name = val;
307 else if(key ==
"z") nuc.Z = val;
308 else if(key ==
"n") nuc.N = val;
309 else if(key ==
"a") nuc.A = val;
310 else if(key ==
"bindingEnergy")
continue;
311 else if(key ==
"bindingEnergyLDMFit")
continue;
312 else if(key ==
"levels") {
314 for(
auto &_item: val.front().items()) {
315 const auto &_key = _item.key();
316 const auto &_val = _item.value();
317 if(_key ==
"decayModes") {
318 for(
auto &mode: _val.items()) {
319 if(mode.value().size()==3) {
320 tkstring type = mode.value().at(
"name");
321 tkstring symbol = mode.value().at(
"symbol");
328 else ratio = mode.value().at(
"value");
329 nuc.decay_modes.emplace_back(type,ratio.
atof());
332 tkstring type = mode.value().at(
"name");
336 nuc.decay_modes.emplace_back(type,ratio.
atof());
340 else if(_key ==
"energy") {
341 if(_val.empty())
continue;
342 if(_val.size()<2)
continue;
343 double ener = _val.at(
"value").get<
tkstring>().atof();
345 glog <<
error <<
" level is not ground state ! " << _val <<
do_endl;
348 else if(_key ==
"massExcess") read_measure(_key, _val, nuc.mass_excess);
349 else if(_key ==
"abundance") {
350 read_measure(_key, _val, nuc.abundance,
true);
351 nuc.abundance.unit =
"%";
354 else if(_key ==
"halflife" || _key ==
"spinAndParity")
continue;
356 glog <<
error <<
"levels: unkown key: " << _key <<
" type: "<< _item.value().type_name() <<
do_endl;
357 cout << _val << endl;
361 else if(key ==
"pairingGap")
continue;
362 else if(key ==
"qValues")
continue;
363 else if(key ==
"separationEnergies")
continue;
364 else if(key ==
"webLinks")
continue;
365 else if(key ==
"BE4DBE2")
continue;
366 else if(key ==
"excitedStateEnergies") {
367 for(
auto &_item: val.items()) {
368 auto &_key = _item.key();
369 auto &_val = _item.value();
370 if(_key ==
"firstExcitedStateEnergy")
continue;
371 if(_key ==
"firstTwoPlusEnergy")
continue;
372 if(_key ==
"firstFourPlusEnergy")
continue;
373 if(_key ==
"firstFourPlusOverFirstTwoPlusEnergy")
continue;
374 if(_key ==
"firstThreeMinusEnergy")
continue;
375 glog <<
error << key <<
": unkown key: " << _key <<
" type: "<< _item.value().type_name() <<
do_endl;
376 cout << _val << endl;
379 else if(key ==
"fissionYields") {
380 for(
auto &_item: val.items()) {
381 auto &_key = _item.key();
382 auto &_val = _item.value();
383 if(_key ==
"FY235U") read_measure(_key, _val, nuc.FY235U);
384 else if(_key ==
"FY238U") read_measure(_key, _val, nuc.FY238U);
385 else if(_key ==
"FY239Pu") read_measure(_key, _val, nuc.FY239Pu);
386 else if(_key ==
"FY241Pu") read_measure(_key, _val, nuc.FY241Pu);
387 else if(_key ==
"FY252Cf") read_measure(_key, _val, nuc.FY252Cf);
388 else if(_key ==
"cFY235U") read_measure(_key, _val, nuc.cFY235U);
389 else if(_key ==
"cFY238U") read_measure(_key, _val, nuc.cFY238U);
390 else if(_key ==
"cFY239Pu") read_measure(_key, _val, nuc.cFY239Pu);
391 else if(_key ==
"cFY241Pu") read_measure(_key, _val, nuc.cFY241Pu);
392 else if(_key ==
"cFY252Cf") read_measure(_key, _val, nuc.cFY252Cf);
394 glog <<
error << key <<
": unkown key: " << _key <<
" type: "<< _item.value().type_name() <<
do_endl;
395 cout << _val << endl;
399 else if(key ==
"quadrupoleDeformation") read_measure(key, val, nuc.quadrupoleDeformation);
400 else if(key ==
"thermalNeutronCapture")
continue;
401 else if(key ==
"thermalNeutronFission")
continue;
404 cout<<
"value: " << endl;
Interface to the sqlite database.
Mother class used to fill the sqlite database.
Representaiton of a sqlite data table.
Decoding of the NUDAT isotope properties.
int fill_database(const char *_json_filename, const char *_gs_filename, int _only_charge=0, int _only_mass=0)
virtual ~tkisotope_builder()
std::string with usefull tricks from TString (ROOT) and KVString (KaliVeda) and more....
static const char * form(const char *_format,...)
std::vector< tkstring > tokenize(const tkstring &_delim=" ") const
Create a vector of string separated by at least one delimiter.
tkstring & remove_all(const tkstring &_s1)
bool contains(const char *_pat, ECaseCompare _cmp=kExact) const
tkstring & append(const tkstring &_st)
tkstring & replace_all(const tkstring &_s1, const tkstring &_s2)
double atof() const
Converts a string to double value.
tklog & error_v(tklog &log)
tklog & error(tklog &log)
tklog & do_endl(tklog &log)
tklog & warning(tklog &log)
data structure used to fill a tkmeasure object from the sqlite database