14#include "tkensdf_builder.h"
21#include "tkensdf_level_rec.h"
22#include "tkensdf_gamma_rec.h"
37 fensdf_reader(_input_folder)
49 fDataBase->begin(
"charge,mass,symbol,isotope_id",
"isotope INNER JOIN element ON isotope.element_id=element.element_id",
"charge>0");
54 message =
"Building '" + flevel_builder->get_table().get_name() +
"' table";
58 while (fDataBase->next()) {
59 tkstring nuc =
tkstring::form(
"%s%s", (*fDataBase)[
"ISOTOPE"][
"mass"].get_value().data(), (*fDataBase)[
"ELEMENT"][
"symbol"].get_value().data());
60 tkstring zz = (*fDataBase)[
"ELEMENT"][
"charge"].get_value();
61 tkstring aa = (*fDataBase)[
"ISOTOPE"][
"mass"].get_value();
62 fIsotopeIndex = ((
tkstring)(*fDataBase)[
"ISOTOPE"][
"isotope_id"].get_value()).
atoi();
65 if (curZ < 1)
continue;
68 bool has_levels = fensdf_reader.open_nuc(nuc,
kensdf);
72 for (
auto &dataset : *fensdf_reader.get_datasets()) {
73 if (dataset.fdsid.begins_with(
"COMMENTS"))
continue;
75 if (date.length() == 6) date = date.
substr(0, 4) +
"-" + date.
substr(4, 2);
76 int datasetIdx =
add_dataset(dataset, nuc.data(), get_dataset_comment(&dataset), date,
"ENSDF");
77 read_dataset(&dataset, datasetIdx);
81 bool has_levelsxundl = fensdf_reader.open_nuc(nuc,
kxundl);
83 for (
auto &dataset : *fensdf_reader.get_datasets()) {
84 if (dataset.fdsid.begins_with(
"COMMENTS"))
continue;
86 if (date.length() == 6) date = date.
substr(0, 4) +
"-" + date.
substr(4, 2);
87 int datasetIdx =
add_dataset(dataset, nuc.data(), get_dataset_comment(&dataset), date,
"XUNDL");
88 read_dataset(&dataset, datasetIdx);
92 glog.progress_bar(117, curZ, message.data());
96 if (has_levels || has_levelsxundl) {
97 fDataBase->exec_sql(
tkstring::form(
"CREATE VIEW lvl%s as select * from level INNER JOIN dataset on level.dataset_id=dataset.dataset_id INNER JOIN isotope on level.isotope_id=isotope.isotope_id INNER JOIN element on isotope.element_id=element.element_id where element.charge=%s AND isotope.mass=%s", nuc.data(), zz.data(), aa.data()));
98 if (fdecay_builder) fDataBase->exec_sql(
tkstring::form(
"CREATE VIEW dec%s as select * from decay INNER JOIN level on decay.level_from_id=level.level_id INNER JOIN dataset on level.dataset_id=dataset.dataset_id INNER JOIN isotope on level.isotope_id=isotope.isotope_id INNER JOIN element on isotope.element_id=element.element_id where element.charge=%s AND isotope.mass=%s", nuc.data(), zz.data(), aa.data()));
102 fDataBase->exec_sql(
"CREATE INDEX isotope_index ON level(isotope_id)");
103 fDataBase->exec_sql(
"CREATE INDEX dataset_index ON level(dataset_id)");
105 fDataBase->exec_sql(
"CREATE INDEX levelfrom_index ON decay(level_from_id)");
106 fDataBase->exec_sql(
"CREATE INDEX levelto_index ON decay(level_to_id)");
108 fensdf_reader.print_record_counters();
122 newname =
tkstring::form(
"%s : ADOPTED LEVELS, GAMMAS", _nucleus.data());
127 (*fDataBase)[
"DATASET"][
"dataset_name"].set_value(newname);
128 if (!_dataset_comment.
is_empty()) (*fDataBase)[
"DATASET"][
"dataset_comment"].set_value(_dataset_comment);
129 if (!_dataset_date.
is_empty()) (*fDataBase)[
"DATASET"][
"dataset_date"].set_value(_dataset_date);
130 if (!_dataset_source.
is_empty()) (*fDataBase)[
"DATASET"][
"dataset_source"].set_value(_dataset_source);
131 (*fDataBase)[
"DATASET"][
"dataset_id"].set_value(fDatasetIndex++);
132 (*fDataBase)[
"DATASET"].push_row();
134 return (fDatasetIndex - 1);
140 bool is_record = fensdf_reader.
first_record(_data_set, record);
147 is_record = fensdf_reader.
next_record(_data_set, record);
154 is_record = fensdf_reader.
next_record(_data_set, record);
160bool tkensdf_builder::read_dataset(
tkensdf_ident_rec *_data_set,
int _dataset_idx)
162 glog.set_class(
"db_ensdf_builder");
163 glog.set_method(
tkstring::form(
"read_levels(%s,%d)", _data_set->
fdsid.data(), _dataset_idx));
165 tkensdf_record the_record;
166 tkensdf_level_rec the_level_record;
167 tkensdf_gamma_rec the_gamma_record;
170 bool is_record = fensdf_reader.first_record(_data_set, record);
172 std::vector<tkensdf_level_rec> flist_of_levels;
174 char *sErrMsg =
nullptr;
175 sqlite3_exec(fDataBase->get_sql_db(),
"BEGIN TRANSACTION",
nullptr,
nullptr, &sErrMsg);
181 is_record = fensdf_reader.next_record(_data_set, record);
190 if (flist_of_levels.empty() && the_record.
is_comment()) {
219 the_gamma_record.
clear();
222 tkensdf_level_rec *level_to =
nullptr;
225 is_record = fensdf_reader.next_record(_data_set, record);
232 is_record = fensdf_reader.next_record(_data_set, record);
249 for (
auto it = flist_of_levels.rbegin() + 1; it != flist_of_levels.rend(); ++it) {
257 if (level_to ==
nullptr) {
262 double last_diff = numeric_limits<double>::max();
263 for (
auto it = flist_of_levels.rbegin() + 1; it != flist_of_levels.rend(); ++it) {
265 if (the_level_record.
get_energy_offset() != level->get_energy_offset())
continue;
266 double diff = abs(lev_to_approx_energy - level->get_energy().value);
267 if (diff > last_diff)
break;
272 if (level_to ==
nullptr) {
273 gdebug <<
"Level_to not found !" <<
do_endl;
276 cout <<
"Level from record: ";
279 cout <<
" record -> " << the_level_record.
get_record() << endl;
281 cout <<
" record -> " << the_gamma_record.
get_record() << endl;
282 if (the_gamma_record.
is_final_level_set()) cout <<
"gamma levels manually set !" << endl;
283 cout <<
" Looking for a level at: ";
285 cout << lev_to_approx_energy <<
" keV in:" << endl;
286 for (
auto it = flist_of_levels.rbegin() + 1; it != flist_of_levels.rend(); ++it) {
288 if (it->is_energy_offset()) cout << it->get_energy_offset() <<
" + ";
289 cout << it->get_energy().value <<
" keV" << endl;
297 gdebug <<
"High energy difference !" <<
do_endl;
300 cout <<
"Level from record: ";
303 cout <<
" record -> " << the_level_record.
get_record() << endl;
305 cout <<
" record -> " << the_gamma_record.
get_record() << endl;
306 if (the_gamma_record.
is_final_level_set()) cout <<
"gamma levels manually set !" << endl;
307 cout <<
" Looking for a level at: ";
309 cout << lev_to_approx_energy <<
" keV in:" << endl;
310 for (
auto it = flist_of_levels.rbegin() + 1; it != flist_of_levels.rend(); ++it) {
312 if (it->is_energy_offset()) cout << it->get_energy_offset() <<
" + ";
313 cout << it->get_energy().value <<
" keV" << endl;
315 cout <<
" Found a level at: " << level_to->
get_energy().
value <<
" keV ==> Diff= " << last_diff <<
" keV" << endl;
322 fdecay_builder->fill_gamma(the_level_record.
flevelid, level_to->
flevelid, the_gamma_record);
324 the_level_record.
clear();
328 is_record = fensdf_reader.next_record(_data_set, record);
335 is_record = fensdf_reader.next_record(_data_set, record);
346 tkensdf_level_rec dummy_rec;
349 flevel_builder->fill_level(_dataset_idx, fIsotopeIndex, dummy_rec, _data_set->
fis_adopted);
350 dummy_rec.
flevelid = flevel_builder->get_level_id();
351 flist_of_levels.emplace_back(dummy_rec);
354 flevel_builder->fill_level(_dataset_idx, fIsotopeIndex, the_level_record, _data_set->
fis_adopted);
355 the_level_record.
flevelid = flevel_builder->get_level_id();
356 flist_of_levels.emplace_back(the_level_record);
360 std::vector<pair<int, tkensdf_level_rec *>> vec;
362 for (
auto it = flist_of_levels.begin(); it != flist_of_levels.end(); it++, idx++) {
364 vec.push_back({idx, (&(*it))});
367 if (vec.size() > 1 && (vec.at(vec.size() - 1).second->get_energy().value < vec.at(vec.size() - 2).second->get_energy().value)) {
368 gdebug <<
"Inverted levels in: " << _data_set->
fnuclide.data() <<
": " << _data_set->
fdsid.data() <<
" [ " << flist_of_levels.at(vec.at(vec.size() - 1).first).get_energy_offset() <<
"+" << flist_of_levels.at(vec.at(vec.size() - 1).first).get_energy().value <<
" ; " << flist_of_levels.at(vec.at(vec.size() - 2).first).get_energy_offset() <<
"+" << flist_of_levels.at(vec.at(vec.size() - 2).first).get_energy().value <<
"]" <<
do_endl;
369 swap(flist_of_levels[vec.at(vec.size() - 1).first], flist_of_levels[vec.at(vec.size() - 2).first]);
372 }
else if (flist_of_levels.size() > 1 && (flist_of_levels.at(flist_of_levels.size() - 1).get_energy().value < flist_of_levels.at(flist_of_levels.size() - 2).get_energy().value)) {
373 gdebug <<
"Inverted levels in: " << _data_set->
fnuclide.data() <<
": " << _data_set->
fdsid.data() <<
" [" << flist_of_levels.at(flist_of_levels.size() - 1).get_energy().value <<
" ; " << flist_of_levels.at(flist_of_levels.size() - 2).get_energy().value <<
"]" <<
do_endl;
374 swap(flist_of_levels[flist_of_levels.size() - 1], flist_of_levels[flist_of_levels.size() - 2]);
378 is_record = fensdf_reader.next_record(_data_set, record);
381 sqlite3_exec(fDataBase->get_sql_db(),
"END TRANSACTION",
nullptr,
nullptr, &sErrMsg);
Interface to the sqlite database.
Main class dedicated to the ENSDF records decoding.
virtual ~tkensdf_builder()
int add_dataset(tkensdf_ident_rec &_dataset, const tkstring &_nucleus, const tkstring &_dataset_comment="", const tkstring &_dataset_date="", const tkstring &_dataset_source="")
tkensdf_builder(tkdatabase *_database, const tkstring &_input_folder)
virtual void analyse_record() override
analyse the record content
virtual bool set_record(const tkstring &_record) override
define the record from a string
bool is_final_level_set()
return true if the information on the final level is manually defined
double get_final_level_energy()
return true if the information on the final level is manually defined
void set_final_level_set(bool _status)
return true if the information on the final level is manually defined
Decodding of the ENSDF identification record properties.
virtual void analyse_record() override
analyse the record content
virtual bool set_record(const tkstring &_record) override
define the record from a string
bool first_record(tkensdf_ident_rec *_dataset, tkstring &record)
move in the current file to the first record of the selected data set
bool next_record(tkensdf_ident_rec *_dataset, tkstring &record)
get the next record of the selected data set
Decodding of the ENSDF records.
const tkstring & get_record()
get record
virtual void add_comment_record(const tkstring &_comment_record, bool _is_continuation=false)
add a continuation record from a string
bool is_energy_offset()
to now if the energy is given with an offset
virtual bool set_record(const tkstring &_record)
define the record from a string. Option false only checks if the record is an identification record
bool is_continuation_record()
to now if the record is a continuation record or not
tkstring fglobal_time_unit
virtual const tkstring & get_comment_record() const
get the continuation record
const tkdb_table::measure_data_struct & get_energy() const
tkstring get_energy_offset()
get_energy_offset
virtual void add_continuation_record(const tkstring &_continuation_record)
add a continuation record from a string
record_type get_record_type()
get record type
bool is_comment()
to now if the record is a comment
std::string with usefull tricks from TString (ROOT) and KVString (KaliVeda) and more....
tkstring copy() const
Returns a copy of this string.
static const char * form(const char *_format,...)
tkstring & remove_all(const tkstring &_s1)
tkstring substr(size_type __pos=0, size_type __n=npos) const
Inlines.
int atoi() const
Converts a string to integer value.
tkstring & remove_all_extra_white_space()
bool contains(const char *_pat, ECaseCompare _cmp=kExact) const
bool begins_with(const char *_s, ECaseCompare _cmp=kExact) const
tkstring & replace_all(const tkstring &_s1, const tkstring &_s2)
tklog & error_v(tklog &log)
tklog & do_endl(tklog &log)