TkN 2.7
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 fvector_of_nuclei.reserve(4000);
83
84 tkdb_table &element = (*gdatabase)["ELEMENT"];
85 tkdb_table &iso_table = (*gdatabase)["ISOTOPE"];
86
87 static const std::array<tkstring, 17> property_names = {
88 "lifetime", // From ENSDF
89 "abundance", "quadrupoleDeformation", "FY235U", "FY238U", "FY239Pu", "FY241Pu", "FY252Cf", "cFY235U", "cFY238U", "cFY239Pu", "cFY241Pu", "cFY252Cf", // From NUDAT
90 "mass_excess", "radius", "magnetic_dipole", "electric_quadrupole" // From primary AME and IAEA tables
91 };
92 std::array<tkdb_table::measure_columns, property_names.size()> property_columns;
93 for (std::size_t index = 0; index < property_names.size(); ++index)
94 property_columns[index] = iso_table.get_measure_columns(property_names[index]);
95
96 // try with isotope.*, element.*
97 gdatabase->begin("isotope.*, element.*", "isotope INNER JOIN element on isotope.element_id=element.element_id");
98
99 while (gdatabase->next()) {
100 shared_ptr<tknucleus> anucleus = make_shared<tknucleus>();
101
102 tkstring name = element["symbol"].get_value();
103 anucleus->felement_symbol = name;
104 anucleus->felement_name = element["element_name"].get_value();
105
106 int zz = element["charge"].get_value().atoi();
107 int aa = iso_table["mass"].get_value().atoi();
108
109 gdebug << aa << name << " loaded" << do_endl;
110
111 name.prepend(iso_table["mass"].get_value());
112
113 anucleus->set_name(name.data());
114 anucleus->fA = aa;
115 anucleus->fZ = zz;
116 anucleus->fN = aa - zz;
117 anucleus->fis_known = true;
118
119 // load element properties
120 for (auto &col : element.get_columns()) {
121 tkstring colname = col.first;
122 if (colname == "element_id") continue;
123 if (colname.ends_with("_unit")) continue;
124
125 tkstring colname_unit = colname + "_unit";
126 tkstring unit("");
127 tkstring value = col.second.get_value();
128 // SQL NULL values are represented by an empty tkdb_column. Do not
129 // expose them as real properties with a numeric value of zero.
130 if (value.is_empty()) continue;
131 if (element.get_columns().count(colname_unit)) {
132 unit = element.get_columns().at(colname_unit).get_value();
133 }
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") {
140 shared_ptr<tkmeasure> data = make_shared<tkmeasure>(value.atof(), unit);
141 data->set_info(tkproperty::kKnown);
142 data->set_type(colname);
143 anucleus->add_property(colname, data);
144 } else if (colname.begins_with("XRay")) {
145 unit = "keV";
146 shared_ptr<tkmeasure> data = make_shared<tkmeasure>(value.atof(), unit);
147 data->set_info(tkproperty::kKnown);
148 data->set_type(colname);
149 if (value.atof() > 0) anucleus->add_property(colname, data);
150 } else {
151 anucleus->add_property_str(colname, value, unit);
152 }
153 }
154
155 // load isotope properties
156 for (std::size_t index = 0; index < property_names.size(); ++index) {
157 const auto &property_name = property_names[index];
158 tkdb_table::measure_data_struct data_struct;
159 iso_table.read_measure(data_struct, property_columns[index]);
160 if (data_struct.filled) {
161 shared_ptr<tkmeasure> data;
162 if (data_struct.err_low > 0. && data_struct.err_high > 0.)
163 data = make_shared<tkmeasure>(data_struct.value, data_struct.unit,
164 data_struct.err_low, data_struct.err_high);
165 else
166 data = make_shared<tkmeasure>(data_struct.value, data_struct.unit, data_struct.err);
167 data->set_info(tkproperty::kKnown);
168 if (!data_struct.info.is_empty()) data->set_info_tag(data_struct.info);
169 data->set_type(property_name);
170
171 if (property_name == "lifetime") {
172 if (data->get_info_tag().contains("STABLE")) {
173 anucleus->fis_stable = true;
174 data->set_error(0);
175 anucleus->add_property(property_name, data, "STABLE", "");
176 } else
177 anucleus->add_property(property_name, data, tkstring::form("%g", data->get_value()));
178 } else {
179 anucleus->add_property(property_name, data);
180 }
181 }
182 }
183
184 tkstring discovery_year = iso_table["isotope_year_discovered"].get_value();
185 if (!discovery_year.is_empty())
186 anucleus->add_property_str("isotope_year_discovered", discovery_year, "");
187
188 tkstring decay_modes = iso_table["decay_modes"].get_value();
189 if (!decay_modes.is_empty())
190 anucleus->add_property_str("decay_modes", decay_modes, "");
191
192 tkstring spin_parity_str = iso_table["spin_parity"].get_value();
193 if (!spin_parity_str.is_empty()) {
194 double spin = iso_table["spin"].get_value().atof();
195 int parity = iso_table["parity"].get_value().atoi();
196
197 anucleus->fspin_parity.set_spin(spin);
198 anucleus->fspin_parity.set_parity(parity);
199 anucleus->fspin_parity.set_from_str(spin_parity_str);
200
201 anucleus->add_property_str("spin_parity", spin_parity_str, "");
202 }
203
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);
210 fmap_of_level_scheme.emplace(name, nullptr);
211 fmap_of_level_scheme_once.emplace(name, make_shared<std::once_flag>());
212
213 if (!fmap_of_symbols.count(anucleus->get_z()))
214 fmap_of_symbols[anucleus->get_z()] = anucleus->get_element_symbol();
215 }
216
217 // separation energy calculation
218 if (!get_nucleus(0, 1) || !get_nucleus(1, 1) || !get_nucleus(2, 4)) return;
219 auto neutron_ME = fmap_of_nuclei_per_z_and_a.at(0).at(1)->get("mass_excess");
220 auto proton_ME = fmap_of_nuclei_per_z_and_a.at(1).at(1)->get("mass_excess");
221 auto alpha_ME = fmap_of_nuclei_per_z_and_a.at(2).at(4)->get("mass_excess");
222 tkmeasure electron_mass(0.51099895000, "MeV", 0.00000000015);
223 for (auto &nuc : fmap_of_nuclei) {
224 auto ME = nuc.second->get("mass_excess");
225 if (!ME) continue;
226 // Sn calculation: Sn(A,Z) = − ME(A,Z) + ME(A−1,Z) + ME(n)
227 auto daughter = get_nucleus(nuc.second->get_z(), nuc.second->get_a() - 1);
228 if (daughter && daughter->get("mass_excess")) {
229 shared_ptr<tkmeasure> Sn = make_shared<tkmeasure>(-*ME + *daughter->get("mass_excess") + *neutron_ME);
230 Sn->set_type("neutronSeparationEnergy");
231 nuc.second->add_property("neutronSeparationEnergy", Sn);
232 }
233 // S2n calculation: S2n(A,Z) = − ME(A,Z) + ME(A−2,Z) + 2*ME(n)
234 daughter = get_nucleus(nuc.second->get_z(), nuc.second->get_a() - 2);
235 if (daughter && daughter->get("mass_excess")) {
236 shared_ptr<tkmeasure> S2n = make_shared<tkmeasure>(-*ME + *daughter->get("mass_excess") + 2. * (*neutron_ME));
237 S2n->set_type("twoNeutronSeparationEnergy");
238 nuc.second->add_property("twoNeutronSeparationEnergy", S2n);
239 }
240 // Sp calculation: Sp(A,Z) = − ME(A,Z) + ME(A−1,Z-1) + ME(p)
241 daughter = get_nucleus(nuc.second->get_z() - 1, nuc.second->get_a() - 1);
242 if (daughter && daughter->get("mass_excess")) {
243 shared_ptr<tkmeasure> Sp = make_shared<tkmeasure>(-*ME + *daughter->get("mass_excess") + *proton_ME);
244 Sp->set_type("protonSeparationEnergy");
245 nuc.second->add_property("protonSeparationEnergy", Sp);
246 }
247 // S2p calculation: S2p(A,Z) = − ME(A,Z) + ME(A−2,Z-2) + 2*ME(p)
248 daughter = get_nucleus(nuc.second->get_z() - 2, nuc.second->get_a() - 2);
249 if (daughter && daughter->get("mass_excess")) {
250 shared_ptr<tkmeasure> S2p = make_shared<tkmeasure>(-*ME + *daughter->get("mass_excess") + 2. * (*proton_ME));
251 S2p->set_type("twoProtonSeparationEnergy");
252 nuc.second->add_property("twoProtonSeparationEnergy", S2p);
253 }
254
255 // Qalpha
256 daughter = get_nucleus(nuc.second->get_z() - 2, nuc.second->get_a() - 4);
257 if (daughter && daughter->get("mass_excess")) {
258 shared_ptr<tkmeasure> Q = make_shared<tkmeasure>(*ME - *daughter->get("mass_excess") - *alpha_ME);
259 Q->set_type("Qalpha");
260 nuc.second->add_property("Qalpha", Q);
261 }
262 // QbetaMinus
263 daughter = get_nucleus(nuc.second->get_z() + 1, nuc.second->get_a());
264 if (daughter && daughter->get("mass_excess")) {
265 shared_ptr<tkmeasure> Q = make_shared<tkmeasure>(*ME - *daughter->get("mass_excess"));
266 Q->set_type("QbetaMinus");
267 nuc.second->add_property("QbetaMinus", Q);
268 }
269 // QbetaMinusOneNeutronEmission
270 daughter = get_nucleus(nuc.second->get_z() + 1, nuc.second->get_a() - 1);
271 if (daughter && daughter->get("mass_excess")) {
272 shared_ptr<tkmeasure> Q = make_shared<tkmeasure>(*ME - *daughter->get("mass_excess") - *neutron_ME);
273 Q->set_type("QbetaMinusOneNeutronEmission");
274 nuc.second->add_property("QbetaMinusOneNeutronEmission", Q);
275 }
276 // QbetaMinusTwoNeutronEmission
277 daughter = get_nucleus(nuc.second->get_z() + 1, nuc.second->get_a() - 2);
278 if (daughter && daughter->get("mass_excess")) {
279 shared_ptr<tkmeasure> Q = make_shared<tkmeasure>(*ME - *daughter->get("mass_excess") - 2. * (*neutron_ME));
280 Q->set_type("QbetaMinusTwoNeutronEmission");
281 nuc.second->add_property("QbetaMinusTwoNeutronEmission", Q);
282 }
283 // QdeltaAlpha: 0.5*(Qa(Z+2,N+2)-Qa(Z,N))
284 daughter = get_nucleus(nuc.second->get_z() + 2, nuc.second->get_a() + 4);
285 if (daughter && daughter->get("mass_excess") && nuc.second->get("Qalpha")) {
286 auto Qa = nuc.second->get("Qalpha");
287 auto Qa2 = *daughter->get("mass_excess") - *ME - *alpha_ME;
288 shared_ptr<tkmeasure> Q = make_shared<tkmeasure>(0.5 * (Qa2 - *Qa));
289 Q->set_type("QdeltaAlpha");
290 nuc.second->add_property("QdeltaAlpha", Q);
291 }
292 // QdoubleBetaMinus
293 daughter = get_nucleus(nuc.second->get_z() + 2, nuc.second->get_a());
294 if (daughter && daughter->get("mass_excess")) {
295 shared_ptr<tkmeasure> Q = make_shared<tkmeasure>(*ME - *daughter->get("mass_excess"));
296 Q->set_type("QdoubleBetaMinus");
297 nuc.second->add_property("QdoubleBetaMinus", Q);
298 }
299 // QelectronCapture
300 daughter = get_nucleus(nuc.second->get_z() - 1, 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("QelectronCapture");
304 nuc.second->add_property("QelectronCapture", Q);
305 }
306 // QdoubleElectronCapture
307 daughter = get_nucleus(nuc.second->get_z() - 2, 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("QdoubleElectronCapture");
311 nuc.second->add_property("QdoubleElectronCapture", Q);
312 }
313 // QelectronCaptureOneProtonEmission
314 daughter = get_nucleus(nuc.second->get_z() - 2, nuc.second->get_a() - 1);
315 if (daughter && daughter->get("mass_excess")) {
316 shared_ptr<tkmeasure> Q = make_shared<tkmeasure>(*ME - *daughter->get("mass_excess") - *proton_ME);
317 Q->set_type("QelectronCaptureOneProtonEmission");
318 nuc.second->add_property("QelectronCaptureOneProtonEmission", Q);
319 }
320 // QpositronEmission
321 daughter = get_nucleus(nuc.second->get_z() - 1, nuc.second->get_a());
322 if (daughter && daughter->get("mass_excess")) {
323 auto q_positron = make_shared<tkmeasure>(*ME - *daughter->get("mass_excess") - 2. * electron_mass);
324 q_positron->set_type("QpositronEmission");
325 nuc.second->add_property("QpositronEmission", q_positron);
326 }
327
328 // binding energy
329 auto q_binding = make_shared<tkmeasure>(1. / nuc.second->get_a() * (nuc.second->get_z() * (*proton_ME) + nuc.second->get_n() * (*neutron_ME) - *ME));
330 q_binding->set_type("binding_energy_overA");
331 nuc.second->add_property("binding_energy_overA", q_binding);
332
333 // pairingGap PG=0.5 x (-1)N x ( 2BE(Z,N) - BE(Z,N-1) -BE(Z,N+1) )
334 auto nuc_minus = get_nucleus(nuc.second->get_z(), nuc.second->get_a() - 1);
335 auto nuc_plus = get_nucleus(nuc.second->get_z(), nuc.second->get_a() + 1);
336 if (nuc_minus && nuc_plus && nuc_minus->get("mass_excess") && nuc_plus->get("mass_excess")) {
337 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")));
338 q_pairing->set_type("pairingGap");
339 nuc.second->add_property("pairingGap", q_pairing);
340 }
341 }
342}
343
345{
346 size_t nnuc = fvector_of_nuclei.size(), inuc = 0;
347 for (const auto &nuc : fvector_of_nuclei) {
348 if (_verbose) glog.progress_bar(nnuc, inuc, "... pre-loading");
349 get_level_scheme(nuc->get_symbol(), nuc->get_z(), nuc->get_a());
350 inuc++;
351 }
352}
353
369vector<shared_ptr<tknucleus>> tkmanager::get_nuclei(const std::function<bool(shared_ptr<tknucleus>)> &_selection)
370{
371 vector<shared_ptr<tknucleus>> res;
372 std::copy_if(fvector_of_nuclei.begin(), fvector_of_nuclei.end(), std::back_inserter(res),
373 [&_selection](const auto &nuc) { return _selection(nuc); });
374 return res;
375}
376
378{
379 tkstring symbol = _nuc.extract_alpha();
380 for (auto &nuc_test : fmap_of_nuclei) {
381 if (nuc_test.first.copy().extract_alpha() == symbol) {
382 _z = nuc_test.second->get_z();
383 return true;
384 }
385 }
386 return false;
387}
388
390{
391 std::lock_guard<std::recursive_mutex> lock(get_mutex());
392 fmax_level_id++;
393 return fmax_level_id;
394}
395
397{
398 std::lock_guard<std::recursive_mutex> lock(get_mutex());
399 fmax_decay_id++;
400 return fmax_decay_id;
401}
402
404{
405 std::lock_guard<std::recursive_mutex> lock(get_mutex());
406 if (_id > fmax_level_id) fmax_level_id = _id;
407}
408
410{
411 std::lock_guard<std::recursive_mutex> lock(get_mutex());
412 if (_id > fmax_decay_id) fmax_decay_id = _id;
413}
414
443void tkmanager::load_drip_lines(const tkstring &json_path)
444{
445 std::ifstream f(json_path);
446 if (!f.is_open()) {
447 glog << error << "tkmanager::load_drip_lines: cannot open " << json_path << do_endl;
448 return;
449 }
450
451 json j;
452 try {
453 f >> j;
454 } catch (const std::exception &e) {
455 glog << error << "tkmanager::load_drip_lines: JSON parse error in "
456 << json_path << " : " << e.what() << do_endl;
457 return;
458 }
459
460 if (!j.is_array()) {
461 glog << error << "tkmanager::load_drip_lines: root is not an array in "
462 << json_path << do_endl;
463 return;
464 }
465
466 fdrip_lines.clear();
467
468 auto push_if_present = [&](const json &o, const char *qname, const char *sname) {
469 if (!o.contains(qname)) return;
470 if (o[qname].is_null()) return;
471
472 tkn_drip_point p;
473 p.Z = o.value("Z", 0);
474 p.N = o.value("N", 0);
475 p.value_mev = o.value(qname, std::numeric_limits<double>::quiet_NaN());
476 // sigma may be absent → keep NaN
477 if (o.contains(sname) && !o[sname].is_null()) {
478 p.sigma_mev = o.value(sname, std::numeric_limits<double>::quiet_NaN());
479 }
480 p.type = qname;
481
482 fdrip_lines[p.type].push_back(std::move(p));
483 };
484
485 try {
486 for (const auto &o : j) {
487 if (!o.is_object()) continue;
488 // Z and N must exist; skip otherwise
489 if (!o.contains("Z") || !o.contains("N")) continue;
490
491 push_if_present(o, "S1n", "S1n_sigma");
492 push_if_present(o, "S2n", "S2n_sigma");
493 push_if_present(o, "S1p", "S1p_sigma");
494 push_if_present(o, "S2p", "S2p_sigma");
495 }
496 } catch (const std::exception &e) {
497 glog << error << "tkmanager::load_drip_lines: error while iterating JSON: "
498 << e.what() << do_endl;
499 fdrip_lines.clear();
500 return;
501 }
502
503 // Sort deterministically by Z, then N
504 for (auto &kv : fdrip_lines) {
505 auto &vec = kv.second;
506 std::sort(vec.begin(), vec.end(), [](const tkn_drip_point &a, const tkn_drip_point &b) {
507 if (a.Z != b.Z) return a.Z < b.Z;
508 return a.N < b.N;
509 });
510 }
511
512 glog << info << "load_drip_lines: loaded " << j.size()
513 << " nuclei objects from " << json_path << do_endl;
514}
515
540std::vector<tkn_drip_point> tkmanager::get_drip_line(const std::string &_type, bool reduce_per_Z)
541{
542 std::lock_guard<std::recursive_mutex> lock(get_mutex());
543 if (fdrip_lines.empty()) {
544 // charge par défaut si pas déjà fait
545 load_drip_lines(tkstring::Form("%s/driplines.json", TKN_DB_DIR));
546 }
547
548 auto it = fdrip_lines.find(_type);
549 if (it == fdrip_lines.end()) {
550 glog << warning << "get_drip_line: unknown type '" << _type << "'" << do_endl;
551 return {};
552 }
553
554 const auto &vec = it->second;
555
556 if (!reduce_per_Z) {
557 return vec;
558 }
559
560 // --- Réduction : garder seulement le point avec min |value| par Z
561 std::unordered_map<int, tkn_drip_point> best_by_Z;
562 for (const auto &p : vec) {
563 auto itZ = best_by_Z.find(p.Z);
564 if (itZ == best_by_Z.end()) {
565 best_by_Z[p.Z] = p;
566 } else {
567 const auto &cur = itZ->second;
568 if (std::isnan(cur.value_mev) ||
569 (!std::isnan(p.value_mev) && std::abs(p.value_mev) < std::abs(cur.value_mev))) {
570 best_by_Z[p.Z] = p;
571 }
572 }
573 }
574
575 std::vector<tkn_drip_point> reduced;
576 reduced.reserve(best_by_Z.size());
577 std::transform(best_by_Z.begin(), best_by_Z.end(), std::back_inserter(reduced),
578 [](const auto &kv) { return kv.second; });
579
580 std::sort(reduced.begin(), reduced.end(), [](const tkn_drip_point &a, const tkn_drip_point &b) {
581 if (a.Z != b.Z) return a.Z < b.Z;
582 return a.N < b.N;
583 });
584
585 return reduced;
586}
587
588#ifdef HAS_ROOT
590ClassImp(tkmanager)
591#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