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");
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();
98 if(dataset.fdsid.begins_with(
"COMMENTS"))
continue;
100 read_dataset(&dataset, datasetIdx);
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)");
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()) {
186 if(record.
contains(
"T$LABEL",tkstring::ECaseCompare::kIgnoreCase) || record.
contains(
"T LABEL",tkstring::ECaseCompare::kIgnoreCase)) {
191 else if(record.
contains(
"d(SIGMA)/d(OMEGA)",tkstring::ECaseCompare::kIgnoreCase)) the_level_record.
fglobal_time_unit =
"skip";
205 the_gamma_record.
clear();
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;
for(
auto it = flist_of_levels.rbegin()+1 ; it != flist_of_levels.rend() ; ++it) {
271 if(it->is_energy_offset()) cout << it->get_energy_offset() <<
" + ";
272 cout << it->get_energy().value <<
" keV" << endl;
276 if(!level_to)
continue;
280 gdebug <<
"High energy difference !"<<
do_endl;
283 cout<<
"Level from record: ";
286 cout<<
" record -> " << the_level_record.
get_record() << endl;
288 cout<<
" record -> " << the_gamma_record.
get_record() << endl;
289 if(the_gamma_record.
is_final_level_set()) cout<<
"gamma levels manually set !" << endl;
290 cout<<
" Looking for a level at: ";
292 cout << lev_to_approx_energy<<
" keV in:"<<endl;
293 for(
auto it = flist_of_levels.rbegin()+1 ; it != flist_of_levels.rend() ; ++it) {
295 if(it->is_energy_offset()) cout << it->get_energy_offset() <<
" + ";
296 cout << it->get_energy().value <<
" keV" << endl;
298 cout<<
" Found a level at: " << level_to->
get_energy().
value<<
" keV ==> Diff= "<<last_diff<<
" keV" << endl;
308 the_level_record.
clear();
312 is_record = fensdf_reader.
next_record(_data_set,record);
317 is_record = fensdf_reader.
next_record(_data_set,record);
333 flist_of_levels.emplace_back(dummy_rec);
338 flist_of_levels.emplace_back(the_level_record);
342 std::vector<pair<int,tkensdf_level_rec*>> vec;
344 for(
auto it = flist_of_levels.begin() ; it != flist_of_levels.end() ; it++, idx++) {
346 vec.push_back({idx,(&(*it))});
349 if(vec.size()>1 && (vec.at(vec.size()-1).second->get_energy().value < vec.at(vec.size()-2).second->get_energy().value)) {
350 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;
351 swap(flist_of_levels[vec.at(vec.size()-1).first],flist_of_levels[vec.at(vec.size()-2).first]);
355 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)) {
356 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;
357 swap(flist_of_levels[flist_of_levels.size()-1],flist_of_levels[flist_of_levels.size()-2]);
362 is_record = fensdf_reader.
next_record(_data_set,record);
365 sqlite3_exec(fDataBase->
get_sql_db(),
"END TRANSACTION",
nullptr,
nullptr, &sErrMsg);
Interface to the sqlite database.
void begin(tkstring _selection, tkstring _from, tkstring _condition="", tkstring _loop_name="default", tkstring _extra_cmd="")
int exec_sql(const char *_cmd)
returns the first value for selection
bool next(const tkstring &_loop_name="default")
executes the select statement
void fill_gamma(const int &_level_idx_from, const int &_level_idx_to, const tkensdf_gamma_rec &_gamma_record)
Main class dedicated to the ENSDF records decoding.
virtual ~tkensdf_builder()
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 open_nuc(const tkstring &_nuc_name, const ensdf_data_type &_ftype=kensdf)
open the file for the slected nucleus and data type, and extract the available data sets
bool first_record(tkensdf_ident_rec *_dataset, tkstring &record)
move in the current file to the first record of the selected data set
void print_record_counters()
print record counters
bool next_record(tkensdf_ident_rec *_dataset, tkstring &record)
get the next record of the selected data set
std::vector< tkensdf_ident_rec > * get_datasets()
get access to the identification records
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
void fill_level(int _dset_idx, int _isotope_idx, const tkensdf_level_rec &_lev_record, bool _adopted)
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)