39#include "tkdatabase.h"
54tkmanager* tkmanager::g_data_manager =
nullptr;
58 if(g_data_manager)
return g_data_manager;
60 std::lock_guard<std::recursive_mutex> lock(get_mutex());
62 if(g_data_manager ==
nullptr) {
66 return g_data_manager;
71 std::lock_guard<std::recursive_mutex> lock(get_mutex());
74 g_data_manager =
this;
79 g_data_manager =
nullptr;
82shared_ptr<tklevel_scheme> tkmanager::get_level_scheme(
const tkn::tkstring &_nuc,
int _zz,
int _aa)
84 if(fmap_of_level_scheme.count(_nuc))
return fmap_of_level_scheme[_nuc];
86 std::lock_guard<std::recursive_mutex> lock(get_mutex());
88 if(fmap_of_level_scheme.count(_nuc)==0) {
89 fmap_of_level_scheme[_nuc] = make_shared<tklevel_scheme>(_nuc,_zz,_aa);
92 return fmap_of_level_scheme[_nuc];
95void tkmanager::preload_nuclei()
98 gdatabase->begin(
"isotope.*, element.*",
"isotope INNER JOIN element on isotope.element_id=element.element_id");
100 while(gdatabase->next()) {
101 tkdb_table& element = (*gdatabase)[
"ELEMENT"];
102 tkdb_table& iso_table = (*gdatabase)[
"ISOTOPE"];
104 shared_ptr<tknucleus> anucleus = make_shared<tknucleus>();
106 tkstring name = element[
"symbol"].get_value();
107 anucleus->felement_symbol = name;
108 anucleus->felement_name = element[
"name"].get_value();
110 int zz = element[
"charge"].get_value().atoi();
111 int aa = iso_table[
"mass"].get_value().atoi();
113 gdebug << aa << name <<
" loaded" <<
do_endl;
115 name.
prepend(iso_table[
"mass"].get_value());
117 anucleus->set_name(name.data());
120 anucleus->fN = aa - zz;
125 if(colname==
"element_id")
continue;
128 tkstring colname_unit = colname +
"_unit";
130 tkstring value = col.second.get_value();
132 unit = element.
get_columns().at(colname_unit).get_value();
134 if( colname ==
"atomic_mass" ||
135 colname ==
"atomic_radius_van_der_Waals" ||
136 colname ==
"boiling_point" ||
137 colname ==
"density" ||
138 colname ==
"ionization_energy" ||
139 colname ==
"melting_point"
141 shared_ptr<tkmeasure> data = make_shared<tkmeasure>(value.
atof(),unit);
143 data->set_type(colname);
144 anucleus->add_property(colname,data);
148 shared_ptr<tkmeasure> data = make_shared<tkmeasure>(value.
atof(),unit);
150 data->set_type(colname);
151 if(value.
atof()>0) anucleus->add_property(colname,data);
154 anucleus->add_property_str(colname,value,unit);
159 vector<tkstring> fNames = {
161 "abundance",
"quadrupoleDeformation",
"FY235U",
"FY238U",
"FY239Pu",
"FY241Pu",
"FY252Cf",
"cFY235U",
"cFY238U",
"cFY239Pu",
"cFY241Pu",
"cFY252Cf",
162 "mass_excess",
"radius",
"magnetic_dipole",
"electric_quadrupole"
165 for(
auto &property_name: fNames) {
169 shared_ptr<tkmeasure> data = make_shared<tkmeasure>(data_struct.
value,data_struct.
unit,data_struct.
err);
172 data->set_type(property_name);
174 if(property_name ==
"lifetime") {
176 if(data->get_info_tag().contains(
"STABLE")) {
177 anucleus->fis_stable =
true;
179 anucleus->add_property(property_name,data,
"STABLE",
"");
181 else anucleus->add_property(property_name,data,
tkstring::form(
"%g",data->get_value()));
184 anucleus->add_property(property_name,data);
189 anucleus->add_property_str(
"isotope_year_discovered",iso_table[
"isotope_year_discovered"].get_value(),
"");
191 tkstring decay_modes = iso_table[
"decay_modes"].get_value();
192 anucleus->add_property_str(
"decay_modes",decay_modes,
"");
194 tkstring spin_parity_str = iso_table[
"spin_parity"].get_value();
195 double spin = iso_table[
"spin"].get_value().atof();
196 int parity = iso_table[
"parity"].get_value().atoi();
198 anucleus->fspin_parity.set_spin(spin);
199 anucleus->fspin_parity.set_parity(parity);
200 anucleus->fspin_parity.set_from_str(spin_parity_str);
202 anucleus->add_property_str(
"spin_parity",spin_parity_str,
"");
204 fmap_of_nuclei[name] = anucleus;
205 fmap_of_nuclei_per_z[anucleus->fZ].push_back(anucleus);
206 fmap_of_nuclei_per_a[anucleus->fA].push_back(anucleus);
207 fmap_of_nuclei_per_n[anucleus->fN].push_back(anucleus);
208 fmap_of_nuclei_per_z_and_a[anucleus->fZ][anucleus->fA] = anucleus;
209 fvector_of_nuclei.push_back(anucleus);
211 if(!fmap_of_symbols.count(anucleus->get_z()))
212 fmap_of_symbols[anucleus->get_z()] = anucleus->get_element_symbol();
217 auto neutron_ME = fmap_of_nuclei_per_z_and_a.at(0).at(1)->get(
"mass_excess");
218 auto proton_ME = fmap_of_nuclei_per_z_and_a.at(1).at(1)->get(
"mass_excess");
219 auto alpha_ME = fmap_of_nuclei_per_z_and_a.at(2).at(4)->get(
"mass_excess");
220 tkmeasure electron_mass(0.51099895000,
"MeV",0.00000000015);
221 for(
auto &nuc: fmap_of_nuclei) {
222 auto ME = nuc.second->get(
"mass_excess");
225 auto daughter =
get_nucleus(nuc.second->get_z(),nuc.second->get_a()-1);
226 if(daughter && daughter->get(
"mass_excess")) {
227 shared_ptr<tkmeasure> Sn = make_shared<tkmeasure>(-*ME + *daughter->get(
"mass_excess") + *neutron_ME);
228 Sn->set_type(
"neutronSeparationEnergy");
229 nuc.second->add_property(
"neutronSeparationEnergy",Sn);
232 daughter =
get_nucleus(nuc.second->get_z(),nuc.second->get_a()-2);
233 if(daughter && daughter->get(
"mass_excess")) {
234 shared_ptr<tkmeasure> S2n = make_shared<tkmeasure>(-*ME + *daughter->get(
"mass_excess") + 2.*(*neutron_ME));
235 S2n->set_type(
"twoNeutronSeparationEnergy");
236 nuc.second->add_property(
"twoNeutronSeparationEnergy",S2n);
239 daughter =
get_nucleus(nuc.second->get_z()-1,nuc.second->get_a()-1);
240 if(daughter && daughter->get(
"mass_excess")) {
241 shared_ptr<tkmeasure> Sp = make_shared<tkmeasure>(-*ME + *daughter->get(
"mass_excess") + *proton_ME);
242 Sp->set_type(
"protonSeparationEnergy");
243 nuc.second->add_property(
"protonSeparationEnergy",Sp);
246 daughter =
get_nucleus(nuc.second->get_z()-2,nuc.second->get_a()-2);
247 if(daughter && daughter->get(
"mass_excess")) {
248 shared_ptr<tkmeasure> S2p = make_shared<tkmeasure>(-*ME + *daughter->get(
"mass_excess") + 2.*(*proton_ME));
249 S2p->set_type(
"twoProtonSeparationEnergy");
250 nuc.second->add_property(
"twoProtonSeparationEnergy",S2p);
254 daughter =
get_nucleus(nuc.second->get_z()-2,nuc.second->get_a()-4);
255 if(daughter && daughter->get(
"mass_excess")) {
256 shared_ptr<tkmeasure> Q = make_shared<tkmeasure>( *ME - *daughter->get(
"mass_excess") - *alpha_ME);
257 Q->set_type(
"Qalpha");
258 nuc.second->add_property(
"Qalpha",Q);
261 daughter =
get_nucleus(nuc.second->get_z()+1,nuc.second->get_a());
262 if(daughter && daughter->get(
"mass_excess")) {
263 shared_ptr<tkmeasure> Q = make_shared<tkmeasure>( *ME - *daughter->get(
"mass_excess"));
264 Q->set_type(
"QbetaMinus");
265 nuc.second->add_property(
"QbetaMinus",Q);
268 daughter =
get_nucleus(nuc.second->get_z()+1,nuc.second->get_a()-1);
269 if(daughter && daughter->get(
"mass_excess")) {
270 shared_ptr<tkmeasure> Q = make_shared<tkmeasure>( *ME - *daughter->get(
"mass_excess") - *neutron_ME);
271 Q->set_type(
"QbetaMinusOneNeutronEmission");
272 nuc.second->add_property(
"QbetaMinusOneNeutronEmission",Q);
275 daughter =
get_nucleus(nuc.second->get_z()+1,nuc.second->get_a()-2);
276 if(daughter && daughter->get(
"mass_excess")) {
277 shared_ptr<tkmeasure> Q = make_shared<tkmeasure>( *ME - *daughter->get(
"mass_excess") - 2.*(*neutron_ME) );
278 Q->set_type(
"QbetaMinusTwoNeutronEmission");
279 nuc.second->add_property(
"QbetaMinusTwoNeutronEmission",Q);
282 daughter =
get_nucleus(nuc.second->get_z()+2,nuc.second->get_a()+4);
283 if(daughter && daughter->get(
"mass_excess") && nuc.second->get(
"Qalpha")) {
284 auto Qa = nuc.second->get(
"Qalpha");
285 auto Qa2 = *daughter->get(
"mass_excess") - *ME - *alpha_ME;
286 shared_ptr<tkmeasure> Q = make_shared<tkmeasure>( 0.5*(Qa2 - *Qa ));
287 Q->set_type(
"QdeltaAlpha");
288 nuc.second->add_property(
"QdeltaAlpha",Q);
291 daughter =
get_nucleus(nuc.second->get_z()+2,nuc.second->get_a());
292 if(daughter && daughter->get(
"mass_excess")) {
293 shared_ptr<tkmeasure> Q = make_shared<tkmeasure>( *ME - *daughter->get(
"mass_excess"));
294 Q->set_type(
"QdoubleBetaMinus");
295 nuc.second->add_property(
"QdoubleBetaMinus",Q);
298 daughter =
get_nucleus(nuc.second->get_z()-1,nuc.second->get_a());
299 if(daughter && daughter->get(
"mass_excess")) {
300 shared_ptr<tkmeasure> Q = make_shared<tkmeasure>( *ME - *daughter->get(
"mass_excess"));
301 Q->set_type(
"QelectronCapture");
302 nuc.second->add_property(
"QelectronCapture",Q);
305 daughter =
get_nucleus(nuc.second->get_z()-2,nuc.second->get_a());
306 if(daughter && daughter->get(
"mass_excess")) {
307 shared_ptr<tkmeasure> Q = make_shared<tkmeasure>( *ME - *daughter->get(
"mass_excess"));
308 Q->set_type(
"QdoubleElectronCapture");
309 nuc.second->add_property(
"QdoubleElectronCapture",Q);
312 daughter =
get_nucleus(nuc.second->get_z()-2,nuc.second->get_a()-1);
313 if(daughter && daughter->get(
"mass_excess")) {
314 shared_ptr<tkmeasure> Q = make_shared<tkmeasure>( *ME - *daughter->get(
"mass_excess") - *proton_ME);
315 Q->set_type(
"QelectronCaptureOneProtonEmission");
316 nuc.second->add_property(
"QelectronCaptureOneProtonEmission",Q);
319 daughter =
get_nucleus(nuc.second->get_z()-1,nuc.second->get_a());
320 if(daughter && daughter->get(
"mass_excess")) {
321 shared_ptr<tkmeasure> Q = make_shared<tkmeasure>( *ME - *daughter->get(
"mass_excess") - 2.*electron_mass);
322 Q->set_type(
"QpositronEmission");
323 nuc.second->add_property(
"QpositronEmission",Q);
327 shared_ptr<tkmeasure> Q = make_shared<tkmeasure>( 1./nuc.second->get_a()*(nuc.second->get_z()*(*proton_ME) + nuc.second->get_n()*(*neutron_ME) - *ME));
328 Q->set_type(
"binding_energy_overA");
329 nuc.second->add_property(
"binding_energy_overA",Q);
332 auto nuc_minus =
get_nucleus(nuc.second->get_z(),nuc.second->get_a()-1);
333 auto nuc_plus =
get_nucleus(nuc.second->get_z(),nuc.second->get_a()+1);
334 if(nuc_minus && nuc_plus && nuc_minus->get(
"mass_excess") && nuc_plus->get(
"mass_excess")) {
335 shared_ptr<tkmeasure> Q = make_shared<tkmeasure>( 0.5 * pow(-1,nuc.second->get_n()) * ( -2* (*ME) + *nuc_minus->get(
"mass_excess") + *nuc_plus->get(
"mass_excess")));
336 Q->set_type(
"pairingGap");
337 nuc.second->add_property(
"pairingGap",Q);
344 size_t nnuc=fvector_of_nuclei.size(),inuc=0;
345 for(
const auto &nuc : fvector_of_nuclei){
346 if(_verbose) glog.progress_bar(nnuc,inuc,
"... pre-loading");
347 get_level_scheme(nuc->get_symbol(),nuc->get_z(),nuc->get_a());
369 vector<shared_ptr<tknucleus>> res;
370 for(
const auto &nuc : fvector_of_nuclei)
371 if(_selection(nuc)) res.push_back(nuc);
377 for(
auto &nuc_test: fmap_of_nuclei) {
378 if(nuc_test.first.copy().extract_alpha() == symbol) {
379 _z = nuc_test.second->get_z();
388 std::lock_guard<std::recursive_mutex> lock(get_mutex());
390 return fmax_level_id;
395 std::lock_guard<std::recursive_mutex> lock(get_mutex());
397 return fmax_decay_id;
Representaiton of a sqlite data table.
void read_measure(measure_data_struct &_struct, const tkstring &_col_base_name)
Manages the database loading and provides access to the physics properties.
int get_new_level_id()
define a new unique level id
shared_ptr< tknucleus > get_nucleus(const tkstring &_nuc)
return a shared pointer to a nucleus from its name
const vector< shared_ptr< tknucleus > > & get_nuclei()
return a vector containing all the known nuclei
int get_new_decay_id()
define a new unique decay id
bool known_element(tkstring _nuc, int &_z)
is the element symbol is known (ex: "C")
void preload_level_schemes(bool _verbose=false)
preload all the level schemes from the database
Stores information on an experimental measure.
std::string with usefull tricks from TString (ROOT) and KVString (KaliVeda) and more....
tkstring extract_alpha()
Returns a tkstring composed only of the alphabetic letters of the original tkstring.
static const char * form(const char *_format,...)
bool ends_with(const char *_s, ECaseCompare _cmp=kExact) const
bool contains(const char *_pat, ECaseCompare _cmp=kExact) const
tkstring & prepend(const tkstring &_st)
bool begins_with(const char *_s, ECaseCompare _cmp=kExact) const
double atof() const
Converts a string to double value.
tklog & do_endl(tklog &log)
data structure used to fill a tkmeasure object from the sqlite database