19#include "tkdb_table.h"
20#include "tklevel_scheme.h"
23#include "tkdatabase.h"
50 if (fA < 0 || fZ < 0)
return;
51 init(_load_default_dataset);
73 vector<shared_ptr<tklevel>> res;
75 std::copy_if(levels.begin(), levels.end(), std::back_inserter(res),
76 [&_selection](
const auto &lvl) { return _selection(lvl); });
96 vector<shared_ptr<tkdecay>> res;
98 std::copy_if(decays.begin(), decays.end(), std::back_inserter(res),
99 [&_selection](
const auto &dec) { return _selection(dec); });
127 glog <<
info <<
" Level scheme of " << fnucleus <<
do_endl;
128 glog <<
info <<
" Options : 'dataset', 'level', 'decay'" <<
do_endl;
131 auto print_group = [&](
const tkstring &source_label) {
132 bool header_printed =
false;
133 for (
auto &dts : fmap_of_dataset) {
134 if (dts.second->get_source() != source_label)
continue;
135 if (!header_printed) {
136 glog <<
info <<
"--- " << source_label <<
" ---" <<
do_endl;
137 header_printed =
true;
139 glog <<
info << dts.second->get_name() <<
" (" << dts.first <<
")";
140 if (dts.second->has_date()) glog <<
" [" << dts.second->get_date() <<
"]";
142 if (_option.
contains(
"com") && dts.second->has_comment()) {
143 const size_t comment_prefix_size = 13;
144 const size_t content_col = comment_prefix_size + 2;
149 print_group(
"ENSDF");
150 print_group(
"XUNDL");
154 fmap_of_dataset[fdatasetid]->print(_data, _option);
157 int _current_data_set = fdatasetid;
158 for (
auto &dataset : fmap_of_dataset) {
159 glog <<
info <<
"dataset : " << dataset.second->get_name() <<
do_endl;
161 dataset.second->print(
"leveldecay");
174 if (fmap_of_dataset_name_id.count(_dataset_name) == 0) {
175 glog <<
warning <<
"dataset '" << _dataset_name <<
"' do not exist for " << fnucleus <<
do_endl;
179 fdatasetid = fmap_of_dataset_name_id[_dataset_name];
189 if (fmap_of_dataset.count(_dataset_id) == 0) {
190 glog <<
warning <<
"dataset with id '" << _dataset_id <<
"' do not exist for " << fnucleus <<
do_endl;
195 fdatasetid = _dataset_id;
196 fmap_of_dataset[fdatasetid]->load_dataset();
218 const char *sep =
"";
226 if (array.size() != 2) {
227 glog <<
error <<
" <nuclear_level_scheme::get_level_energy()> invalid argument '" << _name <<
"'. Syntax: '[spin][parity][rank]'." <<
do_endl;
232 rank = array.at(1).atoi();
235 for (
const auto &lvlp :
get_levels([](
auto lvl) {
return (lvl->get_spin_parity() !=
nullptr); })) {
236 auto jpistr = lvlp->get_spin_parity()->get_jpi_str();
245 }
else if (jpistr.equal_to(
tkstring::form(
"%s%s", spin.data(), sep))) {
250 if (idx == rank)
return lvlp;
266 shared_ptr<tklevel> clostest_lev;
267 double best_ediff = 1e6;
270 if (_offset != lev->get_offset_bandhead())
continue;
272 if (_offset.
is_empty() && !lev->get_offset_bandhead().is_empty())
continue;
273 if (_offset.
contains(
"dec") && lev->get_decays_down().size() == 0)
continue;
275 if (ediff < best_ediff) {
283void tklevel_scheme::init(
bool _load_default_dataset)
285 gdatabase->begin(
"DISTINCT dataset.dataset_id, dataset.dataset_name, dataset.dataset_comment, dataset.dataset_date, dataset.dataset_source",
"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()));
287 while (gdatabase->next(
tkstring::form(
"read_dataset_%s", fnucleus.data()))) {
288 tkdb_table &datasets = (*gdatabase)[
"DATASET"];
289 int ds_id = datasets[
"dataset_id"].get_value().atoi();
290 fmap_of_dataset_name_id[datasets[
"dataset_name"].get_value()] = ds_id;
291 auto ds = make_shared<tkdataset>(tkdataset(fnucleus, fZ, fA, datasets[
"dataset_name"].get_value(), ds_id));
292 if (!datasets[
"dataset_comment"].is_empty()) ds->fdataset_comment = datasets[
"dataset_comment"].get_value();
293 if (!datasets[
"dataset_date"].is_empty()) ds->fdataset_date = datasets[
"dataset_date"].get_value();
294 if (!datasets[
"dataset_source"].is_empty()) ds->fdataset_source = datasets[
"dataset_source"].get_value();
295 fmap_of_dataset[ds_id] = ds;
297 tkstring default_dataset = fnucleus.data();
298 default_dataset +=
" : ADOPTED LEVELS, GAMMAS";
299 gdebug <<
"looking for dataset : " << default_dataset <<
do_endl;
300 bool found = (fmap_of_dataset_name_id.count(default_dataset) > 0);
301 gdebug << (found ?
"" :
"not ") <<
"found " << (found ? fmap_of_dataset_name_id[default_dataset.data()] : -1) <<
do_endl;
304 fdatasetid = fmap_of_dataset_name_id[default_dataset.data()];
307 for (
const auto &dts : fmap_of_dataset) {
308 glog <<
warning <<
tkstring::form(
"%5s", fnucleus.data()) <<
" -- no 'ADOPTED LEVELS' dataset : '" << dts.second->get_name() <<
"' used instead." <<
do_endl;
309 fdatasetid = dts.first;
314 if (fmap_of_dataset.empty()) {
315 tkstring datasetname =
"EMPTY";
317 fmap_of_dataset_name_id[datasetname] = fdatasetid;
318 fmap_of_dataset[fdatasetid] = make_shared<tkdataset>(tkdataset(fnucleus, fZ, fA, datasetname, fdatasetid));
324void tkdataset::check_yrast(shared_ptr<tklevel> _lvl)
327 if (_lvl->get_spin_parity()->get_spin().is_known()) {
328 int TwoJ = (int)(_lvl->get_spin_parity()->get_spin().get_value() * 2 + 0.5);
329 if (!fyrastmap_exact.count(TwoJ)) {
330 fyrastmap_exact[TwoJ] = _lvl;
331 _lvl->fisYrast_exact =
true;
334 if (!fyrastmap_uncertain.count(TwoJ)) {
335 fyrastmap_uncertain[TwoJ] = _lvl;
336 _lvl->fisYrast_uncertain =
true;
339 }
else if (!_lvl->get_spin_parity_str().is_empty() && !_lvl->get_spin_parity_str().contains(
",")) {
340 tkstring tmp = _lvl->get_spin_parity_str().copy().remove_all(
"(").remove_all(
")").remove_all(
"+").remove_all(
"-");
345 TwoJ = tmp.
atoi() * 2;
346 if (!fyrastmap_uncertain.count(TwoJ)) {
347 fyrastmap_uncertain[TwoJ] = _lvl;
348 _lvl->fisYrast_uncertain =
true;
354void tkdataset::load_dataset()
359 auto t_0 = std::chrono::high_resolution_clock::now();
360 gdebug <<
"loading levels for dataset '" << fname <<
"' of " << fnucleus <<
do_endl;
363 gdatabase->begin(
"DISTINCT level.*",
"level",
tkstring::form(
"dataset_id=%d", fid));
365 while (gdatabase->next()) {
370 gmanager->set_max_level_id(
id);
375 shared_ptr<tklevel> lvl = make_shared<tklevel>(
id, energy_struc);
376 lvl->fbelongs_to_nucleus = fnucleus;
382 col = &(*levels)[
"level_spin_parity"];
384 col = &(*levels)[
"level_spin"];
386 col = &(*levels)[
"level_parity"];
389 if (!spin_parity_str.
is_empty()) lvl->set_jpi(spin, parity, spin_parity_str);
393 if (lifetime_struc.
filled) lvl->set_lifetime(lifetime_struc);
395 col = &(*levels)[
"level_comment"];
397 col = &(*levels)[
"level_uncertain"];
400 flevels.push_back(lvl);
404 for (
const auto &lvl : flevels) {
405 fmapoflevels[lvl->get_id()] = lvl;
409 auto t_1 = std::chrono::high_resolution_clock::now();
410 gdebug <<
"loading decays for dataset '" << fname <<
"' of " << fnucleus <<
do_endl;
413 gdatabase->begin(
"DISTINCT decay.*",
"decay INNER JOIN level on decay.level_from_id=level.level_id ",
tkstring::form(
"dataset_id=%d", fid));
415 while (gdatabase->next()) {
417 int level_from = -1.;
424 gmanager->set_max_decay_id(
id);
426 col = &(*decay)[
"decay_type"];
428 col = &(*decay)[
"level_from_id"];
430 col = &(*decay)[
"level_to_id"];
433 shared_ptr<tkdecay> dec =
nullptr;
439 dec = make_shared<tkgammadecay>(
id, level_from, level_to, energy_struc);
440 shared_ptr<tkgammadecay> gamma = dynamic_pointer_cast<tkgammadecay>(dec);
443 decay->
read_measure(relative_intensity_struc,
"decay_relative_intensity");
444 if (relative_intensity_struc.
filled) gamma->set_relative_intensity(relative_intensity_struc);
446 col = &(*decay)[
"decay_multipolarity"];
450 decay->
read_measure(mixing_ratio_struc,
"decay_mixing_ratio");
451 if (mixing_ratio_struc.
filled) gamma->set_mixing_ratio(mixing_ratio_struc);
454 decay->
read_measure(conv_coeff_struc,
"decay_conv_coeff");
455 if (conv_coeff_struc.
filled) gamma->set_conv_coeff(conv_coeff_struc);
460 if (transprob_struc.
filled) gamma->set_transition_probability(transprob_struc);
461 transprob_struc.
clear();
463 if (transprob_struc.
filled) gamma->set_transition_probability(transprob_struc);
464 transprob_struc.
clear();
466 if (transprob_struc.
filled) gamma->set_transition_probability(transprob_struc);
467 transprob_struc.
clear();
469 if (transprob_struc.
filled) gamma->set_transition_probability(transprob_struc);
473 col = &(*decay)[
"decay_comment"];
475 col = &(*decay)[
"decay_uncertain"];
478 fdecays.push_back(dec);
479 fdecays.back()->set_levels(fmapoflevels.at(level_from), fmapoflevels.at(level_to));
481 for (
auto &dec : fdecays) {
482 fmapoflevels.at(dec->get_level_from_id())->add_decay_down(dec);
483 fmapoflevels.at(dec->get_level_to_id())->add_decay_up(dec);
487 auto t_2 = std::chrono::high_resolution_clock::now();
489 auto dt01 = std::chrono::duration<double, std::milli>(t_1 - t_0).count() * 0.001;
490 auto dt12 = std::chrono::duration<double, std::milli>(t_2 - t_1).count() * 0.001;
492 gdebug << std::fixed << std::setprecision(4) <<
"time level: "
496 gdebug << std::fixed << std::setprecision(4) <<
"time decays: "
511 glog <<
info <<
"dataset '" << fname <<
"' contains " << flevels.size() <<
" levels" <<
do_endl;
512 glog <<
info <<
"dataset '" << fname <<
"' contains " << fdecays.size() <<
" decays" <<
do_endl;
513 bool first_level_printed =
false;
514 for (
auto &lev : flevels) {
515 if (_option.
contains(
"yrastt") && !lev->is_yrast(
true))
517 else if (_option.
contains(
"yrast") && !_option.
contains(
"yrastt") && !lev->is_yrast())
519 if (first_level_printed) cout << std::endl;
520 first_level_printed =
true;
522 for (
auto &dec : lev->get_decays_down()) {
523 tkstring decay_option =
"quiet;levto";
524 if (_option.
contains(
"com")) decay_option +=
";com";
525 cout << setw(13) <<
"" <<
"-> ";
526 dec->print(decay_option);
529 }
else if (_data.
contains(
"level")) {
531 std::cout << std::setw(15) << left <<
"symbol" << std::setw(15) <<
"levelid"
532 << std::setw(15) << left <<
"energy (keV)"
533 << std::setw(15) << left <<
"energy error"
534 << std::setw(15) << left <<
"spin parity"
535 << std::setw(15) << left <<
"t1/2"
536 << std::setw(15) << left <<
"t1/2 error"
537 << std::setw(15) << left <<
"t1/2 unit" << std::endl;
539 glog <<
info <<
"dataset '" << fname <<
"' contains " << flevels.size() <<
" levels:" <<
do_endl;
540 for (
auto &lev : flevels) {
541 if (_option.
contains(
"yrastt") && !lev->is_yrast(
true))
543 else if (_option.
contains(
"yrast") && !_option.
contains(
"yrastt") && !lev->is_yrast())
545 if (_option.
contains(
"tab")) std::cout << std::setw(15) << left << fnucleus;
548 }
else if (_data.
contains(
"decay")) {
550 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;
552 glog <<
info <<
"dataset '" << fname <<
"' contains " << fdecays.size() <<
" decays:" <<
do_endl;
553 for (
auto &dec : fdecays) {
554 if (_option.
contains(
"tab")) std::cout << std::setw(15) << left << fnucleus;
576 double spin_val = -1.;
577 int parity_val = -1.;
579 tkdb_table::measure_data_struct lvl_properties{_ener, _unc, 0, 0, _unit};
580 shared_ptr<tklevel> lvl = make_shared<tklevel>(gmanager->get_new_level_id(), lvl_properties);
587 lvl->set_jpi(spin_val, parity_val, _jpistr);
590 lvl->fbelongs_to_nucleus = fnucleus;
593 auto it = std::lower_bound(flevels.begin(), flevels.end(), lvl,
594 [](
const std::shared_ptr<tklevel> &a,
const std::shared_ptr<tklevel> &b) {
595 return a->get_energy() < b->get_energy();
597 flevels.insert(it, lvl);
600 fmapoflevels[lvl->get_id()] = lvl;
622shared_ptr<tkgammadecay>
tkdataset::add_gamma_decay(shared_ptr<tklevel> _lvlfrom, shared_ptr<tklevel> _lvlto,
double _ener,
double _unc)
624 if (_ener == 0.) _ener = _lvlfrom->get_energy() - _lvlto->get_energy();
626 tkdb_table::measure_data_struct energy_struc{_ener, _unc, 0., 0.,
"keV"};
628 shared_ptr<tkgammadecay> decay = make_shared<tkgammadecay>(gmanager->get_new_decay_id(), _lvlfrom->get_id(), _lvlto->get_id(), energy_struc);
629 decay->set_levels(_lvlfrom, _lvlto);
630 fdecays.push_back(decay);
631 _lvlfrom->add_decay_down(decay);
632 _lvlto->add_decay_up(decay);
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
Simple structure to store a table column.
tkstring get_value() const
Representaiton of a sqlite data table.
void read_measure(measure_data_struct &_struct, const tkstring &_col_base_name)
Manages the available datasets for a given nucleus.
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
tklevel_scheme(const tkstring &_nuc, int _zz, int _aa, bool _load_default_dataset=true)
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.
std::string wrap_text(const tkstring &_text, size_t _first_content_col, size_t _continuation_col, size_t _max_line_width=80)
tklog & error(tklog &log)
tklog & do_endl(tklog &log)
tklog & warning(tklog &log)
tklog & comment(tklog &log)
data structure used to fill a tkmeasure object from the sqlite database