37#include "tkensdf_builder.h"
44#include "tkensdf_level_rec.h"
45#include "tkensdf_gamma_rec.h"
61 fensdf_reader(_input_folder)
73 fDataBase->begin(
"charge,mass,symbol,isotope_id",
"isotope INNER JOIN element ON isotope.element_id=element.element_id",
"charge>0");
78 message =
"Building '" + flevel_builder->get_table().get_name() +
"' table";
82 while(fDataBase->next())
84 tkstring nuc =
tkstring::form(
"%s%s",(*fDataBase)[
"ISOTOPE"][
"mass"].get_value().data(),(*fDataBase)[
"ELEMENT"][
"symbol"].get_value().data());
85 tkstring zz = (*fDataBase)[
"ELEMENT"][
"charge"].get_value();
86 tkstring aa = (*fDataBase)[
"ISOTOPE"][
"mass"].get_value();
87 fIsotopeIndex = ((
tkstring)(*fDataBase)[
"ISOTOPE"][
"isotope_id"].get_value()).
atoi();
93 bool has_levels = fensdf_reader.open_nuc(nuc,
kensdf);
97 for(
auto &dataset: *fensdf_reader.get_datasets()) {
98 if(dataset.fdsid.begins_with(
"COMMENTS"))
continue;
100 read_dataset(&dataset, datasetIdx);
104 bool has_levelsxundl = fensdf_reader.open_nuc(nuc,
kxundl);
106 for(
auto &dataset: *fensdf_reader.get_datasets()) {
107 if(dataset.fdsid.begins_with(
"COMMENTS"))
continue;
109 read_dataset(&dataset, datasetIdx);
113 glog.progress_bar(117,curZ,message.data()); oldZ=curZ;
116 if(has_levels||has_levelsxundl){
117 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()));
118 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()));
122 fDataBase->exec_sql(
"CREATE INDEX isotope_index ON level(isotope_id)");
123 fDataBase->exec_sql(
"CREATE INDEX dataset_index ON level(dataset_id)");
125 fDataBase->exec_sql(
"CREATE INDEX levelfrom_index ON decay(level_from_id)");
126 fDataBase->exec_sql(
"CREATE INDEX levelto_index ON decay(level_to_id)");
128 fensdf_reader.print_record_counters();
142 newname =
tkstring::form(
"%s : ADOPTED LEVELS, GAMMAS",_comment.data());
147 (*fDataBase)[
"DATASET"][
"dataset_name"].set_value(newname);
148 (*fDataBase)[
"DATASET"][
"dataset_comment"].set_value(_comment);
149 (*fDataBase)[
"DATASET"][
"dataset_id"].set_value(fDatasetIndex++);
150 (*fDataBase)[
"DATASET"].push_row();
152 return (fDatasetIndex-1);
155bool tkensdf_builder::read_dataset(
tkensdf_ident_rec *_data_set,
int _dataset_idx)
157 glog.set_class(
"db_ensdf_builder");
158 glog.set_method(
tkstring::form(
"read_levels(%s,%d)", _data_set->
fdsid.data(),_dataset_idx));
165 bool is_record = fensdf_reader.
first_record(_data_set,record);
167 std::vector<tkensdf_level_rec> flist_of_levels;
169 char * sErrMsg =
nullptr;
170 sqlite3_exec(fDataBase->
get_sql_db(),
"BEGIN TRANSACTION",
nullptr,
nullptr, &sErrMsg);
176 is_record = fensdf_reader.
next_record(_data_set,record);
185 if(flist_of_levels.empty() && the_record.
is_comment()) {
205 the_gamma_record.
clear();
208 tkensdf_level_rec *level_to =
nullptr;
211 is_record = fensdf_reader.next_record(_data_set,record);
216 is_record = fensdf_reader.next_record(_data_set,record);
233 for(
auto it = flist_of_levels.rbegin()+1 ; it != flist_of_levels.rend() ; ++it) {
241 if(level_to ==
nullptr) {
246 double last_diff = numeric_limits<double>::max();
247 for(
auto it = flist_of_levels.rbegin()+1 ; it != flist_of_levels.rend() ; ++it) {
250 double diff = abs(lev_to_approx_energy-level->get_energy().value);
251 if(diff>last_diff)
break;
256 if(level_to ==
nullptr) {
257 gdebug <<
"Level_to not found !"<<
do_endl;
260 cout<<
"Level from record: ";
263 cout<<
" record -> " << the_level_record.
get_record() << endl;
265 cout<<
" record -> " << the_gamma_record.
get_record() << endl;
266 if(the_gamma_record.
is_final_level_set()) cout<<
"gamma levels manually set !" << endl;
267 cout<<
" Looking for a level at: ";
269 cout << lev_to_approx_energy<<
" keV in:"<<endl;
270 for(
auto it = flist_of_levels.rbegin()+1 ; it != flist_of_levels.rend() ; ++it) {
272 if(it->is_energy_offset()) cout << it->get_energy_offset() <<
" + ";
273 cout << it->get_energy().value <<
" keV" << endl;
281 gdebug <<
"High energy difference !"<<
do_endl;
284 cout<<
"Level from record: ";
287 cout<<
" record -> " << the_level_record.
get_record() << endl;
289 cout<<
" record -> " << the_gamma_record.
get_record() << endl;
290 if(the_gamma_record.
is_final_level_set()) cout<<
"gamma levels manually set !" << endl;
291 cout<<
" Looking for a level at: ";
293 cout << lev_to_approx_energy<<
" keV in:"<<endl;
294 for(
auto it = flist_of_levels.rbegin()+1 ; it != flist_of_levels.rend() ; ++it) {
296 if(it->is_energy_offset()) cout << it->get_energy_offset() <<
" + ";
297 cout << it->get_energy().value <<
" keV" << endl;
299 cout<<
" Found a level at: " << level_to->
get_energy().
value<<
" keV ==> Diff= "<<last_diff<<
" keV" << endl;
306 fdecay_builder->fill_gamma(the_level_record.
flevelid, level_to->
flevelid, the_gamma_record);
309 the_level_record.
clear();
313 is_record = fensdf_reader.next_record(_data_set,record);
318 is_record = fensdf_reader.next_record(_data_set,record);
329 tkensdf_level_rec dummy_rec;
332 flevel_builder->fill_level(_dataset_idx, fIsotopeIndex, dummy_rec, _data_set->
fis_adopted);
333 dummy_rec.
flevelid = flevel_builder->get_level_id();
334 flist_of_levels.emplace_back(dummy_rec);
337 flevel_builder->fill_level(_dataset_idx, fIsotopeIndex, the_level_record, _data_set->
fis_adopted);
338 the_level_record.
flevelid = flevel_builder->get_level_id();
339 flist_of_levels.emplace_back(the_level_record);
343 std::vector<pair<int,tkensdf_level_rec*>> vec;
345 for(
auto it = flist_of_levels.begin() ; it != flist_of_levels.end() ; it++, idx++) {
347 vec.push_back({idx,(&(*it))});
350 if(vec.size()>1 && (vec.at(vec.size()-1).second->get_energy().value < vec.at(vec.size()-2).second->get_energy().value)) {
351 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;
352 swap(flist_of_levels[vec.at(vec.size()-1).first],flist_of_levels[vec.at(vec.size()-2).first]);
356 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)) {
357 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;
358 swap(flist_of_levels[flist_of_levels.size()-1],flist_of_levels[flist_of_levels.size()-2]);
363 is_record = fensdf_reader.next_record(_data_set,record);
366 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)