14#include "tkensdf_builder.h"
21#include "tkensdf_level_rec.h"
22#include "tkensdf_gamma_rec.h"
38 fensdf_reader(_input_folder)
50 fDataBase->begin(
"charge,mass,symbol,isotope_id",
"isotope INNER JOIN element ON isotope.element_id=element.element_id",
"charge>0");
55 message =
"Building '" + flevel_builder->get_table().get_name() +
"' table";
59 while(fDataBase->next())
61 tkstring nuc =
tkstring::form(
"%s%s",(*fDataBase)[
"ISOTOPE"][
"mass"].get_value().data(),(*fDataBase)[
"ELEMENT"][
"symbol"].get_value().data());
62 tkstring zz = (*fDataBase)[
"ELEMENT"][
"charge"].get_value();
63 tkstring aa = (*fDataBase)[
"ISOTOPE"][
"mass"].get_value();
64 fIsotopeIndex = ((
tkstring)(*fDataBase)[
"ISOTOPE"][
"isotope_id"].get_value()).
atoi();
70 bool has_levels = fensdf_reader.open_nuc(nuc,
kensdf);
74 for(
auto &dataset: *fensdf_reader.get_datasets()) {
75 if(dataset.fdsid.begins_with(
"COMMENTS"))
continue;
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 read_dataset(&dataset, datasetIdx);
90 glog.progress_bar(117,curZ,message.data()); oldZ=curZ;
93 if(has_levels||has_levelsxundl){
94 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()));
95 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()));
99 fDataBase->exec_sql(
"CREATE INDEX isotope_index ON level(isotope_id)");
100 fDataBase->exec_sql(
"CREATE INDEX dataset_index ON level(dataset_id)");
102 fDataBase->exec_sql(
"CREATE INDEX levelfrom_index ON decay(level_from_id)");
103 fDataBase->exec_sql(
"CREATE INDEX levelto_index ON decay(level_to_id)");
105 fensdf_reader.print_record_counters();
119 newname =
tkstring::form(
"%s : ADOPTED LEVELS, GAMMAS",_comment.data());
124 (*fDataBase)[
"DATASET"][
"dataset_name"].set_value(newname);
125 (*fDataBase)[
"DATASET"][
"dataset_comment"].set_value(_comment);
126 (*fDataBase)[
"DATASET"][
"dataset_id"].set_value(fDatasetIndex++);
127 (*fDataBase)[
"DATASET"].push_row();
129 return (fDatasetIndex-1);
132bool tkensdf_builder::read_dataset(
tkensdf_ident_rec *_data_set,
int _dataset_idx)
134 glog.set_class(
"db_ensdf_builder");
135 glog.set_method(
tkstring::form(
"read_levels(%s,%d)", _data_set->
fdsid.data(),_dataset_idx));
142 bool is_record = fensdf_reader.
first_record(_data_set,record);
144 std::vector<tkensdf_level_rec> flist_of_levels;
146 char * sErrMsg =
nullptr;
147 sqlite3_exec(fDataBase->
get_sql_db(),
"BEGIN TRANSACTION",
nullptr,
nullptr, &sErrMsg);
153 is_record = fensdf_reader.
next_record(_data_set,record);
162 if(flist_of_levels.empty() && the_record.
is_comment()) {
182 the_gamma_record.
clear();
185 tkensdf_level_rec *level_to =
nullptr;
188 is_record = fensdf_reader.next_record(_data_set,record);
193 is_record = fensdf_reader.next_record(_data_set,record);
210 for(
auto it = flist_of_levels.rbegin()+1 ; it != flist_of_levels.rend() ; ++it) {
218 if(level_to ==
nullptr) {
223 double last_diff = numeric_limits<double>::max();
224 for(
auto it = flist_of_levels.rbegin()+1 ; it != flist_of_levels.rend() ; ++it) {
227 double diff = abs(lev_to_approx_energy-level->get_energy().value);
228 if(diff>last_diff)
break;
233 if(level_to ==
nullptr) {
234 gdebug <<
"Level_to not found !"<<
do_endl;
237 cout<<
"Level from record: ";
240 cout<<
" record -> " << the_level_record.
get_record() << endl;
242 cout<<
" record -> " << the_gamma_record.
get_record() << endl;
243 if(the_gamma_record.
is_final_level_set()) cout<<
"gamma levels manually set !" << endl;
244 cout<<
" Looking for a level at: ";
246 cout << lev_to_approx_energy<<
" keV in:"<<endl;
247 for(
auto it = flist_of_levels.rbegin()+1 ; it != flist_of_levels.rend() ; ++it) {
249 if(it->is_energy_offset()) cout << it->get_energy_offset() <<
" + ";
250 cout << it->get_energy().value <<
" keV" << endl;
258 gdebug <<
"High energy difference !"<<
do_endl;
261 cout<<
"Level from record: ";
264 cout<<
" record -> " << the_level_record.
get_record() << endl;
266 cout<<
" record -> " << the_gamma_record.
get_record() << endl;
267 if(the_gamma_record.
is_final_level_set()) cout<<
"gamma levels manually set !" << endl;
268 cout<<
" Looking for a level at: ";
270 cout << lev_to_approx_energy<<
" keV in:"<<endl;
271 for(
auto it = flist_of_levels.rbegin()+1 ; it != flist_of_levels.rend() ; ++it) {
273 if(it->is_energy_offset()) cout << it->get_energy_offset() <<
" + ";
274 cout << it->get_energy().value <<
" keV" << endl;
276 cout<<
" Found a level at: " << level_to->
get_energy().
value<<
" keV ==> Diff= "<<last_diff<<
" keV" << endl;
283 fdecay_builder->fill_gamma(the_level_record.
flevelid, level_to->
flevelid, the_gamma_record);
286 the_level_record.
clear();
290 is_record = fensdf_reader.next_record(_data_set,record);
295 is_record = fensdf_reader.next_record(_data_set,record);
306 tkensdf_level_rec dummy_rec;
309 flevel_builder->fill_level(_dataset_idx, fIsotopeIndex, dummy_rec, _data_set->
fis_adopted);
310 dummy_rec.
flevelid = flevel_builder->get_level_id();
311 flist_of_levels.emplace_back(dummy_rec);
314 flevel_builder->fill_level(_dataset_idx, fIsotopeIndex, the_level_record, _data_set->
fis_adopted);
315 the_level_record.
flevelid = flevel_builder->get_level_id();
316 flist_of_levels.emplace_back(the_level_record);
320 std::vector<pair<int,tkensdf_level_rec*>> vec;
322 for(
auto it = flist_of_levels.begin() ; it != flist_of_levels.end() ; it++, idx++) {
324 vec.push_back({idx,(&(*it))});
327 if(vec.size()>1 && (vec.at(vec.size()-1).second->get_energy().value < vec.at(vec.size()-2).second->get_energy().value)) {
328 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;
329 swap(flist_of_levels[vec.at(vec.size()-1).first],flist_of_levels[vec.at(vec.size()-2).first]);
333 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)) {
334 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;
335 swap(flist_of_levels[flist_of_levels.size()-1],flist_of_levels[flist_of_levels.size()-2]);
340 is_record = fensdf_reader.next_record(_data_set,record);
343 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()
tkensdf_builder(tkdatabase *_database, const tkstring &_input_folder)
int add_dataset(tkensdf_ident_rec &_dataset, const tkstring &_comment)
Decodding of the ENSDF gamma 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 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.
Decodding of the ENSDF level 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
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,...)
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)