42#include "tkdb_table.h"
43#include "tklevel_scheme.h"
46#include "tkdatabase.h"
73 if(fA<0||fZ<0)
return;
96 vector<shared_ptr<tklevel>> res;
98 std::copy_if(levels.begin(), levels.end(), std::back_inserter(res),
99 [&_selection](
const auto &lvl) { return _selection(lvl); });
119 vector<shared_ptr<tkdecay>> res;
121 std::copy_if(decays.begin(), decays.end(), std::back_inserter(res),
122 [&_selection](
const auto &dec) { return _selection(dec); });
151 glog <<
info <<
" Level scheme of " << fnucleus <<
do_endl;
152 glog <<
info <<
" Options : 'dataset', 'level', 'decay'" <<
do_endl;
155 glog <<
info <<
"Available datasets are : " <<
do_endl;
156 for(
auto &dts : fmap_of_dataset) glog <<
info << dts.second->get_name() <<
" (" << dts.first <<
")" <<
do_endl;
160 fmap_of_dataset[fdatasetid]->print(_data, _option);
163 int _current_data_set = fdatasetid;
164 for(
auto &dataset: fmap_of_dataset) {
165 glog <<
info <<
"dataset : " << dataset.second->get_name() <<
do_endl;
167 dataset.second->print(
"leveldecay");
180 if(fmap_of_dataset_name_id.count(_dataset_name)==0) {
181 glog <<
warning <<
"dataset '" << _dataset_name <<
"' do not exist for " << fnucleus <<
do_endl;
185 fdatasetid = fmap_of_dataset_name_id[_dataset_name];
195 if(fmap_of_dataset.count(_dataset_id)==0) {
196 glog <<
warning <<
"dataset with id '" << _dataset_id <<
"' do not exist for " << fnucleus <<
do_endl;
201 fdatasetid = _dataset_id;
202 fmap_of_dataset[fdatasetid]->load_dataset();
224 const char* sep =
"";
226 else if(_name.
contains(
"-")) {sep =
"-";}
229 if(array.size()!=2) {
230 glog <<
error <<
" <nuclear_level_scheme::get_level_energy()> invalid argument '" << _name <<
"'. Syntax: '[spin][parity][rank]'." <<
do_endl;
235 rank = array.at(1).atoi();
238 for(
const auto &lvlp :
get_levels([](
auto lvl) {
return (lvl->get_spin_parity()!=
nullptr);})) {
239 auto jpistr = lvlp->get_spin_parity()->get_jpi_str();
249 else if(jpistr.equal_to(
tkstring::form(
"%s%s",spin.data(),sep))) {
254 if(idx==rank)
return lvlp;
270 shared_ptr<tklevel> clostest_lev;
271 double best_ediff=1e6;
274 if(_offset != lev->get_offset_bandhead())
continue;
276 if(_offset.
is_empty() && !lev->get_offset_bandhead().is_empty())
continue;
277 if(_offset.
contains(
"dec") && lev->get_decays_down().size()==0)
continue;
279 if(ediff<best_ediff) {
287void tklevel_scheme::init()
289 gdatabase->begin(
"DISTINCT dataset.dataset_id, dataset.dataset_name",
"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",
tkstring::form(
"element.charge=%d AND isotope.mass=%d",fZ,fA),
tkstring::form(
"read_dataset_%s",fnucleus.data()));
291 while(gdatabase->next(
tkstring::form(
"read_dataset_%s",fnucleus.data()))) {
292 tkdb_table& datasets = (*gdatabase)[
"DATASET"];
293 fmap_of_dataset_name_id[datasets[
"dataset_name"].get_value()] = datasets[
"dataset_id"].get_value().atoi();
294 fmap_of_dataset[datasets[
"dataset_id"].get_value().atoi()] = make_shared<tkdataset>(
tkdataset(fnucleus,fZ,fA,datasets[
"dataset_name"].get_value(),datasets[
"dataset_id"].get_value().atoi()));
296 tkstring default_dataset = fnucleus.data();
297 default_dataset +=
" : ADOPTED LEVELS, GAMMAS";
298 gdebug <<
"looking for dataset : " << default_dataset <<
do_endl;
299 bool found = (fmap_of_dataset_name_id.count(default_dataset)>0);
300 gdebug << (found?
"":
"not ") <<
"found " << (found?fmap_of_dataset_name_id[default_dataset.data()]:-1) <<
do_endl;
302 if(found)
select_dataset(fmap_of_dataset_name_id[default_dataset.data()]);
304 for(
const auto &dts : fmap_of_dataset) {
305 glog <<
warning <<
tkstring::form(
"%5s",fnucleus.data()) <<
" -- no 'ADOPTED LEVELS' dataset : '" << dts.second->get_name() <<
"' used instead." <<
do_endl;
310 if(fmap_of_dataset.empty()) {
311 tkstring datasetname =
"EMPTY";
313 fmap_of_dataset_name_id[datasetname] = fdatasetid;
314 fmap_of_dataset[fdatasetid] = make_shared<tkdataset>(tkdataset(fnucleus,fZ,fA,datasetname,fdatasetid));
320void tkdataset::check_yrast(shared_ptr<tklevel> _lvl)
323 if(_lvl->get_spin_parity()->get_spin().is_known()) {
324 int TwoJ = (int)(_lvl->get_spin_parity()->get_spin().get_value()*2+0.5);
325 if(!fyrastmap_exact.count(TwoJ)) {
326 fyrastmap_exact[TwoJ] = _lvl;
327 _lvl->fisYrast_exact =
true;
330 if(!fyrastmap_uncertain.count(TwoJ)) {
331 fyrastmap_uncertain[TwoJ] = _lvl;
332 _lvl->fisYrast_uncertain =
true;
336 else if(!_lvl->get_spin_parity_str().is_empty() && !_lvl->get_spin_parity_str().contains(
",")) {
337 tkstring tmp = _lvl->get_spin_parity_str().copy().remove_all(
"(").remove_all(
")").remove_all(
"+").remove_all(
"-");
340 else TwoJ = tmp.
atoi()*2;
341 if(!fyrastmap_uncertain.count(TwoJ)) {
342 fyrastmap_uncertain[TwoJ] = _lvl;
343 _lvl->fisYrast_uncertain =
true;
349void tkdataset::load_dataset()
354 auto t_0 = std::chrono::high_resolution_clock::now();
355 gdebug <<
"loading levels for dataset '" << fname <<
"' of " << fnucleus <<
do_endl;
358 gdatabase->begin(
"DISTINCT level.*",
"level",
tkstring::form(
"dataset_id=%d",fid));
360 while(gdatabase->next()) {
361 tkdb_table *levels = &(*gdatabase)[
"LEVEL"];
362 tkdb_column *col = &(*levels)[
"level_id"];
365 gmanager->set_max_level_id(
id);
367 tkdb_table::measure_data_struct energy_struc;
370 shared_ptr<tklevel> lvl = make_shared<tklevel>(
id,energy_struc);
371 lvl->fbelongs_to_nucleus = fnucleus;
375 tkstring spin_parity_str =
"";
377 col = &(*levels)[
"level_spin_parity"];
379 col = &(*levels)[
"level_spin"];
381 col = &(*levels)[
"level_parity"];
384 if(!spin_parity_str.
is_empty()) lvl->set_jpi(spin,parity,spin_parity_str);
386 tkdb_table::measure_data_struct lifetime_struc;
388 if(lifetime_struc.
filled) lvl->set_lifetime(lifetime_struc);
390 col = &(*levels)[
"level_comment"];
392 col = &(*levels)[
"level_uncertain"];
395 flevels.push_back(lvl);
399 for(
const auto &lvl: flevels) {
400 fmapoflevels[lvl->get_id()] = lvl;
404 auto t_1 = std::chrono::high_resolution_clock::now();
405 gdebug <<
"loading decays for dataset '" << fname <<
"' of " << fnucleus <<
do_endl;
408 gdatabase->begin(
"DISTINCT decay.*",
"decay INNER JOIN level on decay.level_from_id=level.level_id ",
tkstring::form(
"dataset_id=%d",fid));
410 while(gdatabase->next()) {
412 int level_from = -1.;
415 tkdb_table *decay = &(*gdatabase)[
"DECAY"];
416 tkdb_column *col = &(*decay)[
"decay_id"];
419 gmanager->set_max_decay_id(
id);
421 col = &(*decay)[
"decay_type"];
423 col = &(*decay)[
"level_from_id"];
425 col = &(*decay)[
"level_to_id"];
428 shared_ptr<tkdecay> dec =
nullptr;
430 tkdb_table::measure_data_struct energy_struc;
434 dec = make_shared<tkgammadecay>(
id, level_from, level_to, energy_struc);
435 shared_ptr<tkgammadecay> gamma = dynamic_pointer_cast<tkgammadecay>(dec);
437 tkdb_table::measure_data_struct relative_intensity_struc;
438 decay->
read_measure(relative_intensity_struc,
"decay_relative_intensity");
439 if(relative_intensity_struc.
filled) gamma->set_relative_intensity(relative_intensity_struc);
441 col = &(*decay)[
"decay_multipolarity"];
444 tkdb_table::measure_data_struct mixing_ratio_struc;
445 decay->
read_measure(mixing_ratio_struc,
"decay_mixing_ratio");
446 if(mixing_ratio_struc.
filled) gamma->set_mixing_ratio(mixing_ratio_struc);
448 tkdb_table::measure_data_struct conv_coeff_struc;
449 decay->
read_measure(conv_coeff_struc,
"decay_conv_coeff");
450 if(conv_coeff_struc.
filled) gamma->set_conv_coeff(conv_coeff_struc);
453 tkdb_table::measure_data_struct transprob_struc;
455 if(transprob_struc.
filled) gamma->set_transition_probability(transprob_struc);
456 transprob_struc.
clear();
458 if(transprob_struc.
filled) gamma->set_transition_probability(transprob_struc);
459 transprob_struc.
clear();
461 if(transprob_struc.
filled) gamma->set_transition_probability(transprob_struc);
462 transprob_struc.
clear();
464 if(transprob_struc.
filled) gamma->set_transition_probability(transprob_struc);
468 col = &(*decay)[
"decay_comment"];
470 col = &(*decay)[
"decay_uncertain"];
473 fdecays.push_back(dec);
474 fdecays.back()->set_levels(fmapoflevels.at(level_from),fmapoflevels.at(level_to));
476 for(
auto &dec: fdecays) {
477 fmapoflevels.at(dec->get_level_from_id())->add_decay_down(dec);
478 fmapoflevels.at(dec->get_level_to_id())->add_decay_up(dec);
483 auto t_2 = std::chrono::high_resolution_clock::now();
485 auto dt01 = std::chrono::duration<double, std::milli>(t_1-t_0).count() * 0.001;
486 auto dt12 = std::chrono::duration<double, std::milli>(t_2-t_1).count() * 0.001;
488 gdebug << std::fixed << std::setprecision(4) <<
"time level: "
492 gdebug << std::fixed << std::setprecision(4) <<
"time decays: "
507 glog <<
info <<
"dataset '" << fname <<
"' contains " << flevels.size() <<
" levels" <<
do_endl;
508 glog <<
info <<
"dataset '" << fname <<
"' contains " << fdecays.size() <<
" decays" <<
do_endl;
509 for(
auto &lev : flevels) {
510 if(_option.
contains(
"yrastt") && !lev->is_yrast(
true))
continue;
511 else if(_option.
contains(
"yrast") && !_option.
contains(
"yrastt") && !lev->is_yrast())
continue;
513 for(
auto &dec : lev->get_decays_down()) {
514 cout<<setw(13)<<
""<<
"-> ";dec->print(
"quiet;levto");
520 std::cout << std::setw(15) << left <<
"symbol" << std::setw(15) <<
"levelid"
521 << std::setw(15) << left <<
"energy (keV)"
522 << std::setw(15) << left <<
"energy error"
523 << std::setw(15) << left <<
"spin parity"
524 << std::setw(15) << left <<
"t1/2"
525 << std::setw(15) << left <<
"t1/2 error"
526 << std::setw(15) << left <<
"t1/2 unit" << std::endl;}
527 else glog <<
info <<
"dataset '" << fname <<
"' contains " << flevels.size() <<
" levels:" <<
do_endl;
528 for(
auto &lev : flevels) {
529 if(_option.
contains(
"yrastt") && !lev->is_yrast(
true))
continue;
530 else if(_option.
contains(
"yrast") && !_option.
contains(
"yrastt") && !lev->is_yrast())
continue;
531 if(_option.
contains(
"tab")) std::cout << std::setw(15)<< left << fnucleus;
536 if(_option.
contains(
"tab")) std::cout << std::setw(15) << left <<
"symbol" << std::setw(15) << left <<
"decayid" << std::setw(15) << left <<
"energy (keV)" << std::setw(15) << left <<
"energy error (keV)" << std::endl;
537 else glog <<
info <<
"dataset '" << fname <<
"' contains " << fdecays.size() <<
" decays:" <<
do_endl;
538 for(
auto &dec : fdecays) {
539 if(_option.
contains(
"tab")) std::cout << std::setw(15) << left << fnucleus;
549 double spin_val = -1.;
550 int parity_val = -1.;
552 tkdb_table::measure_data_struct lvl_properties{_ener,_unc,0,0,_unit};
553 shared_ptr<tklevel> lvl = make_shared<tklevel>(gmanager->get_new_level_id(),lvl_properties);
555 spin.
set(_jpistr);parity.
set(_jpistr);
559 lvl->set_jpi(spin_val,parity_val,_jpistr);
562 lvl->fbelongs_to_nucleus = fnucleus;
565 auto it = std::lower_bound(flevels.begin(), flevels.end(), lvl,
566 [](
const std::shared_ptr<tklevel>& a,
const std::shared_ptr<tklevel>& b) {
567 return a->get_energy() < b->get_energy();
569 flevels.insert(it, lvl);
572 fmapoflevels[lvl->get_id()] = lvl;
577shared_ptr<tkgammadecay>
tkdataset::add_gamma_decay(shared_ptr<tklevel> _lvlfrom, shared_ptr<tklevel> _lvlto,
double _ener,
double _unc)
579 if(_ener==0.) _ener = _lvlfrom->get_energy() - _lvlto->get_energy();
581 tkdb_table::measure_data_struct energy_struc{_ener,_unc,0.,0.,
"keV"};
583 shared_ptr<tkgammadecay> decay = make_shared<tkgammadecay>(gmanager->get_new_decay_id(), _lvlfrom->get_id(), _lvlto->get_id(), energy_struc);
584 decay->set_levels(_lvlfrom,_lvlto);
585 fdecays.push_back(decay);
586 _lvlfrom->add_decay_down(decay);
587 _lvlto->add_decay_up(decay);
Stores information on a specific dataset.
shared_ptr< tklevel > add_level(double _ener, double _unc, tkstring _unit, tkstring _jpistr)
manually add a new level to the dataset
shared_ptr< tkgammadecay > add_gamma_decay(shared_ptr< tklevel > _lvlfrom, shared_ptr< tklevel > _lvlto, double _ener=0., double _unc=0.)
add a new decay between two levels to the dataset
friend class tklevel_scheme
tkstring get_value() const
Representaiton of a sqlite data table.
void read_measure(measure_data_struct &_struct, const tkstring &_col_base_name)
tklevel_scheme(const tkstring &_nuc, int _zz, int _aa)
void print(const tkstring &_data="", const tkstring &_option="")
print the level scheme information
const std::vector< shared_ptr< tklevel > > & get_levels()
get the vector containing all the levels
bool select_dataset(const tkstring &_dataset_name)
select a dataset using its name
const shared_ptr< tkdataset > & get_dataset()
returns the current dataset
shared_ptr< tklevel > get_level(const tkstring &_name, bool _exact=true)
get the level corresponding to the given name
const std::vector< shared_ptr< tkdecay > > & get_decays()
get the vector containing all the decays
virtual bool is_parity(tkparity::eparity _parity)
test the parity value
virtual void set(const tkstring &_st)
define the parity from a string
bool is_known() const
to get some information about this data
double get_value()
To get the spin as a double.
void set(int n, int d=1)
define the spin value
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)
int atoi() const
Converts a string to integer value.
bool contains(const char *_pat, ECaseCompare _cmp=kExact) const
double atof() const
Converts a string to double value.
tklog & error(tklog &log)
tklog & do_endl(tklog &log)
tklog & warning(tklog &log)
tklog & comment(tklog &log)