TkN 2.7.1
Toolkit for Nuclei
Loading...
Searching...
No Matches
tkmanager.cpp
1/********************************************************************************
2 * Copyright (c) : Université de Lyon 1, CNRS/IN2P3, UMR5822, *
3 * IP2I, F-69622 Villeurbanne Cedex, France *
4 * Normandie Université, ENSICAEN, UNICAEN, CNRS/IN2P3, *
5 * LPC Caen, F-14000 Caen, France *
6 * Contibutor(s) : *
7 * Jérémie Dudouet jeremie.dudouet@cnrs.fr [2020] *
8 * Diego Gruyer diego.gruyer@cnrs.fr [2020] *
9 * *
10 * Licensed under the MIT License <http://opensource.org/licenses/MIT>. *
11 * SPDX-License-Identifier: MIT *
12 ********************************************************************************/
13
14#include <algorithm>
15#include <atomic>
16#include <array>
17#include <fstream>
18#include <iterator>
19
20#include "tkmanager.h"
21#include "tklog.h"
22#include "tkdatabase.h"
23#include "json.hpp"
24
25namespace tkn {
33
34}
35
36using namespace tkn;
37using json = nlohmann::json;
38
40{
41 static tkmanager *instance = new tkmanager();
42 return instance;
43}
44
46{
47 std::lock_guard<std::recursive_mutex> lock(get_mutex());
48
49 preload_nuclei();
50
51}
52
53tkmanager::~tkmanager() = default;
54
56{
57 const auto scheme = fmap_of_level_scheme.find(_nuc);
58 return scheme != fmap_of_level_scheme.end() &&
59 std::atomic_load_explicit(&scheme->second, std::memory_order_acquire) != nullptr;
60}
61
62shared_ptr<tklevel_scheme> tkmanager::get_level_scheme(const tkn::tkstring &_nuc, int _zz, int _aa)
63{
64 const auto scheme = fmap_of_level_scheme.find(_nuc);
65 const auto once = fmap_of_level_scheme_once.find(_nuc);
66 if (scheme == fmap_of_level_scheme.end() || once == fmap_of_level_scheme_once.end())
67 return make_shared<tklevel_scheme>(_nuc, _zz, _aa);
68
69 std::call_once(*once->second, [&] {
70 // tklevel_scheme construction still reads through the legacy global
71 // gdatabase cursor. Serialise only that construction phase; cached
72 // read access below remains independent between threads.
73 std::lock_guard<std::mutex> load_lock(flevel_scheme_load_mutex);
74 auto loaded = make_shared<tklevel_scheme>(_nuc, _zz, _aa);
75 std::atomic_store_explicit(&scheme->second, std::move(loaded), std::memory_order_release);
76 });
77 return std::atomic_load_explicit(&scheme->second, std::memory_order_acquire);
78}
79
80void tkmanager::preload_nuclei()
81{
82 // open() already reported the failure; do not query a null connection.
83 if (!gdatabase->get_sql_db()) return;
84
85 fvector_of_nuclei.reserve(4000);
86
87 tkdb_table &element = (*gdatabase)["ELEMENT"];
88 tkdb_table &iso_table = (*gdatabase)["ISOTOPE"];
89
90 static const std::array<tkstring, 17> property_names = {
91 "lifetime", // From ENSDF
92 "abundance", "quadrupoleDeformation", "FY235U", "FY238U", "FY239Pu", "FY241Pu", "FY252Cf", "cFY235U", "cFY238U", "cFY239Pu", "cFY241Pu", "cFY252Cf", // From NUDAT
93 "mass_excess", "radius", "magnetic_dipole", "electric_quadrupole" // From primary AME and IAEA tables
94 };
95 std::array<tkdb_table::measure_columns, property_names.size()> property_columns;
96 for (std::size_t index = 0; index < property_names.size(); ++index)
97 property_columns[index] = iso_table.get_measure_columns(property_names[index]);
98
99 // try with isotope.*, element.*
100 gdatabase->begin("isotope.*, element.*", "isotope INNER JOIN element on isotope.element_id=element.element_id");
101
102 while (gdatabase->next()) {
103 shared_ptr<tknucleus> anucleus = make_shared<tknucleus>();
104
105 tkstring name = element["symbol"].get_value();
106 anucleus->felement_symbol = name;
107 anucleus->felement_name = element["element_name"].get_value();
108
109 int zz = element["charge"].get_value().atoi();
110 int aa = iso_table["mass"].get_value().atoi();
111
112 gdebug << aa << name << " loaded" << do_endl;
113
114 name.prepend(iso_table["mass"].get_value());
115
116 anucleus->set_name(name.data());
117 anucleus->fA = aa;
118 anucleus->fZ = zz;
119 anucleus->fN = aa - zz;
120 anucleus->fis_known = true;
121
122 // load element properties
123 for (auto &col : element.get_columns()) {
124 tkstring colname = col.first;
125 if (colname == "element_id") continue;
126 if (colname.ends_with("_unit")) continue;
127
128 tkstring colname_unit = colname + "_unit";
129 tkstring unit("");
130 tkstring value = col.second.get_value();
131 // SQL NULL values are represented by an empty tkdb_column. Do not
132 // expose them as real properties with a numeric value of zero.
133 if (value.is_empty()) continue;
134 if (element.get_columns().count(colname_unit)) {
135 unit = element.get_columns().at(colname_unit).get_value();
136 }
137 if (colname == "atomic_mass" ||
138 colname == "atomic_radius_van_der_Waals" ||
139 colname == "boiling_point" ||
140 colname == "density" ||
141 colname == "ionization_energy" ||
142 colname == "melting_point") {
143 shared_ptr<tkmeasure> data = make_shared<tkmeasure>(value.atof(), unit);
144 data->set_info(tkproperty::kKnown);
145 data->set_type(colname);
146 anucleus->add_property(colname, data);
147 } else if (colname.begins_with("XRay")) {
148 unit = "keV";
149 shared_ptr<tkmeasure> data = make_shared<tkmeasure>(value.atof(), unit);
150 data->set_info(tkproperty::kKnown);
151 data->set_type(colname);
152 if (value.atof() > 0) anucleus->add_property(colname, data);
153 } else {
154 anucleus->add_property_str(colname, value, unit);
155 }
156 }
157
158 // load isotope properties
159 for (std::size_t index = 0; index < property_names.size(); ++index) {
160 const auto &property_name = property_names[index];
161 tkdb_table::measure_data_struct data_struct;
162 iso_table.read_measure(data_struct, property_columns[index]);
163 if (data_struct.filled) {
164 shared_ptr<tkmeasure> data;
165 if (data_struct.err_low > 0. && data_struct.err_high > 0.)
166 data = make_shared<tkmeasure>(data_struct.value, data_struct.unit,
167 data_struct.err_low, data_struct.err_high);
168 else
169 data = make_shared<tkmeasure>(data_struct.value, data_struct.unit, data_struct.err);
170 data->set_info(tkproperty::kKnown);
171 if (!data_struct.info.is_empty()) data->set_info_tag(data_struct.info);
172 data->set_type(property_name);
173 if (property_name == "lifetime")
174 data->set_type(gunits->get_type(data->get_unit_key()) == gunits->kEnergy ? "decay width" : "half-life");
175
176 if (property_name == "lifetime") {
177 if (data->get_info_tag().contains("STABLE")) {
178 anucleus->fis_stable = true;
179 data->set_error(0);
180 anucleus->add_property(property_name, data, "STABLE", "");
181 } else
182 anucleus->add_property(property_name, data, tkstring::form("%g", data->get_value()));
183 } else {
184 anucleus->add_property(property_name, data);
185 }
186 }
187 }
188
189 tkstring discovery_year = iso_table["isotope_year_discovered"].get_value();
190 if (!discovery_year.is_empty())
191 anucleus->add_property_str("isotope_year_discovered", discovery_year, "");
192
193 tkstring decay_modes = iso_table["decay_modes"].get_value();
194 if (!decay_modes.is_empty())
195 anucleus->add_property_str("decay_modes", decay_modes, "");
196
197 tkstring spin_parity_str = iso_table["spin_parity"].get_value();
198 if (!spin_parity_str.is_empty()) {
199 double spin = iso_table["spin"].get_value().atof();
200 int parity = iso_table["parity"].get_value().atoi();
201
202 anucleus->fspin_parity.set_spin(spin);
203 anucleus->fspin_parity.set_parity(parity);
204 anucleus->fspin_parity.set_from_str(spin_parity_str);
205
206 anucleus->add_property_str("spin_parity", spin_parity_str, "");
207 }
208
209 fmap_of_nuclei[name] = anucleus;
210 fmap_of_nuclei_per_z[anucleus->fZ].push_back(anucleus);
211 fmap_of_nuclei_per_a[anucleus->fA].push_back(anucleus);
212 fmap_of_nuclei_per_n[anucleus->fN].push_back(anucleus);
213 fmap_of_nuclei_per_z_and_a[anucleus->fZ][anucleus->fA] = anucleus;
214 fvector_of_nuclei.push_back(anucleus);
215 fmap_of_level_scheme.emplace(name, nullptr);
216 fmap_of_level_scheme_once.emplace(name, make_shared<std::once_flag>());
217
218 if (!fmap_of_symbols.count(anucleus->get_z()))
219 fmap_of_symbols[anucleus->get_z()] = anucleus->get_element_symbol();
220 }
221
222 // separation energy calculation
223 if (!get_nucleus(0, 1) || !get_nucleus(1, 1) || !get_nucleus(2, 4)) return;
224 auto neutron_ME = fmap_of_nuclei_per_z_and_a.at(0).at(1)->get("mass_excess");
225 auto proton_ME = fmap_of_nuclei_per_z_and_a.at(1).at(1)->get("mass_excess");
226 auto alpha_ME = fmap_of_nuclei_per_z_and_a.at(2).at(4)->get("mass_excess");
227 tkmeasure electron_mass(0.51099895000, "MeV", 0.00000000015);
228 for (auto &nuc : fmap_of_nuclei) {
229 auto ME = nuc.second->get("mass_excess");
230 if (!ME) continue;
231 // Sn calculation: Sn(A,Z) = − ME(A,Z) + ME(A−1,Z) + ME(n)
232 auto daughter = get_nucleus(nuc.second->get_z(), nuc.second->get_a() - 1);
233 if (daughter && daughter->get("mass_excess")) {
234 shared_ptr<tkmeasure> Sn = make_shared<tkmeasure>(-*ME + *daughter->get("mass_excess") + *neutron_ME);
235 Sn->set_type("neutronSeparationEnergy");
236 nuc.second->add_property("neutronSeparationEnergy", Sn);
237 }
238 // S2n calculation: S2n(A,Z) = − ME(A,Z) + ME(A−2,Z) + 2*ME(n)
239 daughter = get_nucleus(nuc.second->get_z(), nuc.second->get_a() - 2);
240 if (daughter && daughter->get("mass_excess")) {
241 shared_ptr<tkmeasure> S2n = make_shared<tkmeasure>(-*ME + *daughter->get("mass_excess") + 2. * (*neutron_ME));
242 S2n->set_type("twoNeutronSeparationEnergy");
243 nuc.second->add_property("twoNeutronSeparationEnergy", S2n);
244 }
245 // Sp calculation: Sp(A,Z) = − ME(A,Z) + ME(A−1,Z-1) + ME(p)
246 daughter = get_nucleus(nuc.second->get_z() - 1, nuc.second->get_a() - 1);
247 if (daughter && daughter->get("mass_excess")) {
248 shared_ptr<tkmeasure> Sp = make_shared<tkmeasure>(-*ME + *daughter->get("mass_excess") + *proton_ME);
249 Sp->set_type("protonSeparationEnergy");
250 nuc.second->add_property("protonSeparationEnergy", Sp);
251 }
252 // S2p calculation: S2p(A,Z) = − ME(A,Z) + ME(A−2,Z-2) + 2*ME(p)
253 daughter = get_nucleus(nuc.second->get_z() - 2, nuc.second->get_a() - 2);
254 if (daughter && daughter->get("mass_excess")) {
255 shared_ptr<tkmeasure> S2p = make_shared<tkmeasure>(-*ME + *daughter->get("mass_excess") + 2. * (*proton_ME));
256 S2p->set_type("twoProtonSeparationEnergy");
257 nuc.second->add_property("twoProtonSeparationEnergy", S2p);
258 }
259
260 // Qalpha
261 daughter = get_nucleus(nuc.second->get_z() - 2, nuc.second->get_a() - 4);
262 if (daughter && daughter->get("mass_excess")) {
263 shared_ptr<tkmeasure> Q = make_shared<tkmeasure>(*ME - *daughter->get("mass_excess") - *alpha_ME);
264 Q->set_type("Qalpha");
265 nuc.second->add_property("Qalpha", Q);
266 }
267 // QbetaMinus
268 daughter = get_nucleus(nuc.second->get_z() + 1, nuc.second->get_a());
269 if (daughter && daughter->get("mass_excess")) {
270 shared_ptr<tkmeasure> Q = make_shared<tkmeasure>(*ME - *daughter->get("mass_excess"));
271 Q->set_type("QbetaMinus");
272 nuc.second->add_property("QbetaMinus", Q);
273 }
274 // QbetaMinusOneNeutronEmission
275 daughter = get_nucleus(nuc.second->get_z() + 1, nuc.second->get_a() - 1);
276 if (daughter && daughter->get("mass_excess")) {
277 shared_ptr<tkmeasure> Q = make_shared<tkmeasure>(*ME - *daughter->get("mass_excess") - *neutron_ME);
278 Q->set_type("QbetaMinusOneNeutronEmission");
279 nuc.second->add_property("QbetaMinusOneNeutronEmission", Q);
280 }
281 // QbetaMinusTwoNeutronEmission
282 daughter = get_nucleus(nuc.second->get_z() + 1, nuc.second->get_a() - 2);
283 if (daughter && daughter->get("mass_excess")) {
284 shared_ptr<tkmeasure> Q = make_shared<tkmeasure>(*ME - *daughter->get("mass_excess") - 2. * (*neutron_ME));
285 Q->set_type("QbetaMinusTwoNeutronEmission");
286 nuc.second->add_property("QbetaMinusTwoNeutronEmission", Q);
287 }
288 // QdeltaAlpha: 0.5*(Qa(Z+2,N+2)-Qa(Z,N))
289 daughter = get_nucleus(nuc.second->get_z() + 2, nuc.second->get_a() + 4);
290 auto alpha_daughter = get_nucleus(nuc.second->get_z() - 2, nuc.second->get_a() - 4);
291 if (daughter && daughter->get("mass_excess") && alpha_daughter && alpha_daughter->get("mass_excess")) {
292 // Simplify before propagating errors: the alpha mass cancels and the
293 // central mass occurs twice, not as two independent measurements.
294 shared_ptr<tkmeasure> Q = make_shared<tkmeasure>(
295 0.5 * (*daughter->get("mass_excess") + *alpha_daughter->get("mass_excess") - 2. * (*ME)));
296 Q->set_type("QdeltaAlpha");
297 nuc.second->add_property("QdeltaAlpha", Q);
298 }
299 // QdoubleBetaMinus
300 daughter = get_nucleus(nuc.second->get_z() + 2, nuc.second->get_a());
301 if (daughter && daughter->get("mass_excess")) {
302 shared_ptr<tkmeasure> Q = make_shared<tkmeasure>(*ME - *daughter->get("mass_excess"));
303 Q->set_type("QdoubleBetaMinus");
304 nuc.second->add_property("QdoubleBetaMinus", Q);
305 }
306 // QelectronCapture
307 daughter = get_nucleus(nuc.second->get_z() - 1, nuc.second->get_a());
308 if (daughter && daughter->get("mass_excess")) {
309 shared_ptr<tkmeasure> Q = make_shared<tkmeasure>(*ME - *daughter->get("mass_excess"));
310 Q->set_type("QelectronCapture");
311 nuc.second->add_property("QelectronCapture", Q);
312 }
313 // QdoubleElectronCapture
314 daughter = get_nucleus(nuc.second->get_z() - 2, nuc.second->get_a());
315 if (daughter && daughter->get("mass_excess")) {
316 shared_ptr<tkmeasure> Q = make_shared<tkmeasure>(*ME - *daughter->get("mass_excess"));
317 Q->set_type("QdoubleElectronCapture");
318 nuc.second->add_property("QdoubleElectronCapture", Q);
319 }
320 // QelectronCaptureOneProtonEmission
321 daughter = get_nucleus(nuc.second->get_z() - 2, nuc.second->get_a() - 1);
322 if (daughter && daughter->get("mass_excess")) {
323 shared_ptr<tkmeasure> Q = make_shared<tkmeasure>(*ME - *daughter->get("mass_excess") - *proton_ME);
324 Q->set_type("QelectronCaptureOneProtonEmission");
325 nuc.second->add_property("QelectronCaptureOneProtonEmission", Q);
326 }
327 // QpositronEmission
328 daughter = get_nucleus(nuc.second->get_z() - 1, nuc.second->get_a());
329 if (daughter && daughter->get("mass_excess")) {
330 auto q_positron = make_shared<tkmeasure>(*ME - *daughter->get("mass_excess") - 2. * electron_mass);
331 q_positron->set_type("QpositronEmission");
332 nuc.second->add_property("QpositronEmission", q_positron);
333 }
334
335 // binding energy
336 auto q_binding = make_shared<tkmeasure>(1. / nuc.second->get_a() * (nuc.second->get_z() * (*proton_ME) + nuc.second->get_n() * (*neutron_ME) - *ME));
337 q_binding->set_type("binding_energy_overA");
338 nuc.second->add_property("binding_energy_overA", q_binding);
339
340 // pairingGap PG=0.5 x (-1)N x ( 2BE(Z,N) - BE(Z,N-1) -BE(Z,N+1) )
341 auto nuc_minus = get_nucleus(nuc.second->get_z(), nuc.second->get_a() - 1);
342 auto nuc_plus = get_nucleus(nuc.second->get_z(), nuc.second->get_a() + 1);
343 if (nuc_minus && nuc_plus && nuc_minus->get("mass_excess") && nuc_plus->get("mass_excess")) {
344 auto q_pairing = make_shared<tkmeasure>(0.5 * pow(-1, nuc.second->get_n()) * (-2 * (*ME) + *nuc_minus->get("mass_excess") + *nuc_plus->get("mass_excess")));
345 q_pairing->set_type("pairingGap");
346 nuc.second->add_property("pairingGap", q_pairing);
347 }
348 }
349}
350
352{
353 size_t nnuc = fvector_of_nuclei.size(), inuc = 0;
354 for (const auto &nuc : fvector_of_nuclei) {
355 if (_verbose) glog.progress_bar(nnuc, inuc, "... pre-loading");
356 get_level_scheme(nuc->get_symbol(), nuc->get_z(), nuc->get_a());
357 inuc++;
358 }
359}
360
376vector<shared_ptr<tknucleus>> tkmanager::get_nuclei(const std::function<bool(shared_ptr<tknucleus>)> &_selection)
377{
378 vector<shared_ptr<tknucleus>> res;
379 std::copy_if(fvector_of_nuclei.begin(), fvector_of_nuclei.end(), std::back_inserter(res),
380 [&_selection](const auto &nuc) { return _selection(nuc); });
381 return res;
382}
383
385{
386 tkstring symbol = _nuc.extract_alpha();
387 for (auto &nuc_test : fmap_of_nuclei) {
388 if (nuc_test.first.copy().extract_alpha() == symbol) {
389 _z = nuc_test.second->get_z();
390 return true;
391 }
392 }
393 return false;
394}
395
397{
398 std::lock_guard<std::recursive_mutex> lock(get_mutex());
399 fmax_level_id++;
400 return fmax_level_id;
401}
402
404{
405 std::lock_guard<std::recursive_mutex> lock(get_mutex());
406 fmax_decay_id++;
407 return fmax_decay_id;
408}
409
411{
412 std::lock_guard<std::recursive_mutex> lock(get_mutex());
413 if (_id > fmax_level_id) fmax_level_id = _id;
414}
415
417{
418 std::lock_guard<std::recursive_mutex> lock(get_mutex());
419 if (_id > fmax_decay_id) fmax_decay_id = _id;
420}
421
450void tkmanager::load_drip_lines(const tkstring &json_path)
451{
452 std::ifstream f(json_path);
453 if (!f.is_open()) {
454 glog << error << "tkmanager::load_drip_lines: cannot open " << json_path << do_endl;
455 return;
456 }
457
458 json j;
459 try {
460 f >> j;
461 } catch (const std::exception &e) {
462 glog << error << "tkmanager::load_drip_lines: JSON parse error in "
463 << json_path << " : " << e.what() << do_endl;
464 return;
465 }
466
467 if (!j.is_array()) {
468 glog << error << "tkmanager::load_drip_lines: root is not an array in "
469 << json_path << do_endl;
470 return;
471 }
472
473 fdrip_lines.clear();
474
475 auto push_if_present = [&](const json &o, const char *qname, const char *sname) {
476 if (!o.contains(qname)) return;
477 if (o[qname].is_null()) return;
478
479 tkn_drip_point p;
480 p.Z = o.value("Z", 0);
481 p.N = o.value("N", 0);
482 p.value_mev = o.value(qname, std::numeric_limits<double>::quiet_NaN());
483 // sigma may be absent → keep NaN
484 if (o.contains(sname) && !o[sname].is_null()) {
485 p.sigma_mev = o.value(sname, std::numeric_limits<double>::quiet_NaN());
486 }
487 p.type = qname;
488
489 fdrip_lines[p.type].push_back(std::move(p));
490 };
491
492 try {
493 for (const auto &o : j) {
494 if (!o.is_object()) continue;
495 // Z and N must exist; skip otherwise
496 if (!o.contains("Z") || !o.contains("N")) continue;
497
498 push_if_present(o, "S1n", "S1n_sigma");
499 push_if_present(o, "S2n", "S2n_sigma");
500 push_if_present(o, "S1p", "S1p_sigma");
501 push_if_present(o, "S2p", "S2p_sigma");
502 }
503 } catch (const std::exception &e) {
504 glog << error << "tkmanager::load_drip_lines: error while iterating JSON: "
505 << e.what() << do_endl;
506 fdrip_lines.clear();
507 return;
508 }
509
510 // Sort deterministically by Z, then N
511 for (auto &kv : fdrip_lines) {
512 auto &vec = kv.second;
513 std::sort(vec.begin(), vec.end(), [](const tkn_drip_point &a, const tkn_drip_point &b) {
514 if (a.Z != b.Z) return a.Z < b.Z;
515 return a.N < b.N;
516 });
517 }
518
519 glog << info << "load_drip_lines: loaded " << j.size()
520 << " nuclei objects from " << json_path << do_endl;
521}
522
547std::vector<tkn_drip_point> tkmanager::get_drip_line(const std::string &_type, bool reduce_per_Z)
548{
549 std::lock_guard<std::recursive_mutex> lock(get_mutex());
550 if (fdrip_lines.empty()) {
551 // charge par défaut si pas déjà fait
552 load_drip_lines(tkstring::Form("%s/driplines.json", TKN_DB_DIR));
553 }
554
555 auto it = fdrip_lines.find(_type);
556 if (it == fdrip_lines.end()) {
557 glog << warning << "get_drip_line: unknown type '" << _type << "'" << do_endl;
558 return {};
559 }
560
561 const auto &vec = it->second;
562
563 if (!reduce_per_Z) {
564 return vec;
565 }
566
567 // --- Réduction : garder seulement le point avec min |value| par Z
568 std::unordered_map<int, tkn_drip_point> best_by_Z;
569 for (const auto &p : vec) {
570 auto itZ = best_by_Z.find(p.Z);
571 if (itZ == best_by_Z.end()) {
572 best_by_Z[p.Z] = p;
573 } else {
574 const auto &cur = itZ->second;
575 if (std::isnan(cur.value_mev) ||
576 (!std::isnan(p.value_mev) && std::abs(p.value_mev) < std::abs(cur.value_mev))) {
577 best_by_Z[p.Z] = p;
578 }
579 }
580 }
581
582 std::vector<tkn_drip_point> reduced;
583 reduced.reserve(best_by_Z.size());
584 std::transform(best_by_Z.begin(), best_by_Z.end(), std::back_inserter(reduced),
585 [](const auto &kv) { return kv.second; });
586
587 std::sort(reduced.begin(), reduced.end(), [](const tkn_drip_point &a, const tkn_drip_point &b) {
588 if (a.Z != b.Z) return a.Z < b.Z;
589 return a.N < b.N;
590 });
591
592 return reduced;
593}
594
595#ifdef HAS_ROOT
597ClassImp(tkmanager)
598#endif
Representaiton of a sqlite data table.
Definition tkdb_table.h:31
std::array< tkdb_column *, 6 > measure_columns
Definition tkdb_table.h:81
void read_measure(measure_data_struct &_struct, const tkstring &_col_base_name)
measure_columns get_measure_columns(const tkstring &_col_base_name)
row & get_columns()
Definition tkdb_table.h:126
void clear()
Definition tklog.h:156
Manages the database loading and provides access to the physics properties.
Definition tkmanager.h:51
void set_max_level_id(int _id)
define the max value of the attributed level ids
static tkmanager * the_data_manager()
Definition tkmanager.cpp:39
int get_new_level_id()
define a new unique level id
std::vector< tkn_drip_point > get_drip_line(const std::string &_type, bool reduce_per_Z=true)
Get the drip line for a given type (optionally reduced per Z)
shared_ptr< tknucleus > get_nucleus(const tkstring &_nuc)
return a shared pointer to a nucleus from its name
Definition tkmanager.h:129
const vector< shared_ptr< tknucleus > > & get_nuclei()
return a vector containing all the known nuclei
Definition tkmanager.h:110
int get_new_decay_id()
define a new unique decay id
virtual ~tkmanager()
void set_max_decay_id(int _id)
define the max value of the attributed level ids
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
bool is_level_scheme_loaded(const tkstring &_nuc)
returns true if the level scheme has already been loaded
Definition tkmanager.cpp:55
std::string with usefull tricks from TString (ROOT) and KVString (KaliVeda) and more....
Definition tkstring.h:33
tkstring extract_alpha()
Returns a tkstring composed only of the alphabetic letters of the original tkstring.
Definition tkstring.cpp:394
static const char * form(const char *_format,...)
Definition tkstring.cpp:438
static tkstring Form(const char *_format,...)
Definition tkstring.cpp:368
bool is_empty() const
Definition tkstring.h:145
bool ends_with(const char *_s, ECaseCompare _cmp=kExact) const
Definition tkstring.cpp:272
tkstring & prepend(const tkstring &_st)
Definition tkstring.h:217
bool begins_with(const char *_s, ECaseCompare _cmp=kExact) const
Definition tkstring.h:166
double atof() const
Converts a string to double value.
Definition tkstring.cpp:226
Definition tklog.cpp:16
tklog & info(tklog &log)
Definition tklog.h:313
tklog & error(tklog &log)
Definition tklog.h:344
tklog & do_endl(tklog &log)
Definition tklog.h:212
tklog & warning(tklog &log)
Definition tklog.h:331
A single drip-line data point.
Definition tkmanager.h:40
int Z
Proton number.
Definition tkmanager.h:41
double value_mev
Quantity value (MeV)
Definition tkmanager.h:43
std::string type
Quantity type: "S1n", "S2n", "S1p", or "S2p".
Definition tkmanager.h:45
int N
Neutron number.
Definition tkmanager.h:42
double sigma_mev
Quantity uncertainty (MeV)
Definition tkmanager.h:44