TkN 2.7.1
Toolkit for Nuclei
Loading...
Searching...
No Matches
tklevel.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 "tklevel.h"
15#include "tkstate_time.h"
16#include "tkstring.h"
17#include "tklog.h"
18
19#include <iomanip>
20#include <sstream>
21#include <string>
22
23using namespace std;
24
25namespace tkn {
33}
34
35using namespace tkn;
36
38 flevel_id(_id),
39 fspin_parity(make_shared<tkspin_parity>())
40{
41 shared_ptr<tkmeasure> energy = make_shared<tkmeasure>(_struc.value, _struc.unit);
42 if (_struc.value >= 0.) energy->set_info(tkproperty::kKnown);
43 if (_struc.err > 0.)
44 energy->set_error(_struc.err);
45 else if (_struc.err_low > 0. && _struc.err_high > 0.)
46 energy->set_error(_struc.err_low, _struc.err_high);
47 if (!_struc.info.is_empty()) energy->set_info_tag(_struc.info);
48 energy->set_type("Level energy");
49 add_property("energy", energy);
50
51 if (energy->get_info_tag().contains(";OFF=")) {
52 int idx = energy->get_info_tag().index(";OFF=");
53 tkstring offset = energy->get_info_tag().substr(idx + 5, 1);
54 set_energy_offset(offset);
55 }
56}
57
59{
60 shared_ptr<tkmeasure> lifetime = make_shared<tkmeasure>(_struc.value, _struc.unit);
61 lifetime->set_info(tkproperty::kKnown);
62 if (_struc.err > 0.)
63 lifetime->set_error(_struc.err);
64 else if (_struc.err_low > 0. && _struc.err_high > 0.)
65 lifetime->set_error(_struc.err_low, _struc.err_high);
66 if (!_struc.info.is_empty()) lifetime->set_info_tag(_struc.info);
67 if (lifetime->get_info_tag().contains("STABLE")) fis_stable = true;
68 lifetime->set_type(gunits->get_type(lifetime->get_unit_key()) == gunits->kEnergy ? "decay width" : "half-life");
69 add_property("lifetime", lifetime, tkstring::form("%g", lifetime->get_value()));
70
71 if (lifetime->get_info_tag().contains(";ISO=")) {
72 fis_isomer = true;
73 int idx = lifetime->get_info_tag().index(";ISO=");
74 fisomer_level = lifetime->get_info_tag().substr(idx + 6, 1).atoi(); // ex= ;ISO=M1 => 1
75 if (fisomer_level == 0) fisomer_level = 1;
76 }
77}
78
79namespace {
80
81shared_ptr<tkmeasure> make_level_measure(const tkdb_table::measure_data_struct &data,
82 const tkstring &type)
83{
84 shared_ptr<tkmeasure> measure;
85 if (data.err_low > 0. && data.err_high > 0.)
86 measure = make_shared<tkmeasure>(data.value, data.unit, data.err_low, data.err_high);
87 else
88 measure = make_shared<tkmeasure>(data.value, data.unit, data.err);
89 measure->set_info(tkproperty::kKnown);
90 if (!data.info.is_empty()) measure->set_info_tag(data.info);
91 measure->set_type(type);
92 return measure;
93}
94
95} // namespace
96
98{
99 add_property("magnetic_dipole", make_level_measure(_struc, "magnetic dipole moment"));
100}
101
103{
104 add_property("electric_quadrupole", make_level_measure(_struc, "electric quadrupole moment"));
105}
106
108{
109 if (!has_property("magnetic_dipole")) return std::nan("1");
110 return get("magnetic_dipole")->get_value();
111}
112
114{
115 if (!has_property("electric_quadrupole")) return std::nan("1");
116 return get("electric_quadrupole")->get_value();
117}
118
119void tklevel::set_jpi(double _spin, int _parity, const tkstring &_jpi_str)
120{
121 if (_spin >= 0) fspin_parity->set_spin(_spin);
122 if (_parity >= 0) fspin_parity->set_parity(_parity);
123 fspin_parity->set_from_str(_jpi_str);
124 add_property_str("spin_parity", _jpi_str, "");
125}
126
136double tklevel::get_energy(const tkunit_manager::units_keys _unit, bool _with_offset)
137{
138 if (gunits->get_type(_unit) != tkunit_manager::units_type::kEnergy) {
139 glog << error << gunits->get_name(_unit) << " is not of 'energy' type (returns nan(1))" << do_endl;
140 return std::nan("1");
141 }
142 if (is_energy_offset() && !_with_offset) {
143 glog << warning << "Level is only known relatively to an offset, use the _with_offset option to get the relative energy" << do_endl;
144 return std::nan("1");
145 }
146 return get("energy")->get_value(_unit);
147}
148
154{
155 return detail::state_time_value(get("lifetime"), is_stable(), unit, false);
156}
157
159{
160 return get_half_life(unit) / std::log(2.);
161}
162
164{
165 return detail::state_time_value(get("lifetime"), is_stable(), unit, true);
166}
167
169{
170 if (!has_property("lifetime")) return std::nan("1");
171 if (gunits->get_type(_unit) != tkunit_manager::units_type::kTime && gunits->get_type(_unit) != tkunit_manager::units_type::kEnergy) {
172 glog << error << gunits->get_name(_unit) << " is not of 'time' or 'energy' type (returns nan(1))" << do_endl;
173 return std::nan("1");
174 }
175 return get("lifetime")->get_value(_unit);
176}
177
183{
184 if (!has_property("lifetime")) return "";
185 tkstring lifetime_str;
186
187 if (is_stable())
188 lifetime_str = "STABLE";
189 else {
190 vector<tkunit_manager::units_keys> units{tkunit_manager::y, tkunit_manager::d, tkunit_manager::h, tkunit_manager::min,
194
195 for (auto &unit : units) {
196 double lifetime = get_lifetime(unit);
197 if (lifetime > 1.) {
198 lifetime_str = tkstring::Form("%.3g %s", lifetime, std::get<0>(tkunit_manager::funits_properties.at(unit)).data());
199 break;
200 }
201 }
202 }
203
204 return lifetime_str;
205}
206
208
213bool tklevel::is_yrast(bool _with_tentative)
214{
215 if (_with_tentative)
216 return fisYrast_uncertain;
217 else
218 return fisYrast_exact;
219}
220
227void tklevel::print(const tkstring &_option)
228{
229 // in line printout
230 if (_option.contains("tab")) {
231 std::cout << std::setw(15) << left << flevel_id;
232 if (is_energy_offset()) std::cout << get_offset_bandhead() << "+";
233 std::cout << std::setw(15) << left << get_energy_measure()->get_value();
234 if (get_energy_measure()->get_error() > 0.)
235 std::cout << std::setw(15) << left << get_energy_measure()->get_error();
236 else
237 std::cout << std::setw(15) << left << " ";
238 if (fspin_parity)
239 std::cout << std::setw(15) << left << fspin_parity->get_jpi_str();
240 if (get_lifetime_measure() && get_lifetime_measure()->get_value() > 0.) {
241 std::cout << std::setw(15) << left << get_lifetime_measure()->get_value();
242 if (get_lifetime_measure()->get_error() > 0.)
243 std::cout << std::setw(15) << left << get_lifetime_measure()->get_error();
244 else
245 std::cout << std::setw(15) << left << " ";
246 std::cout << std::setw(15) << left << get_lifetime_measure()->get_unit();
247 } else {
248 std::cout << std::setw(15) << left << " "
249 << std::setw(15) << left << " "
250 << std::setw(15) << left << " ";
251 }
252 std::cout << std::endl;
253 } else {
254 constexpr size_t print_label_width = 14;
255 std::ostringstream level_message;
256 level_message << std::left << std::setw(print_label_width) << "Nuclear level:";
257
258 tkmeasure energy_print = *get_energy_measure();
259 energy_print.set_type("energy");
260
261 glog << info << level_message.str() << " " << &energy_print;
262 if (fspin_parity)
263 glog << " ; Jpi: " << setw(4) << fspin_parity->get_jpi_str();
264 if (get_lifetime_measure() && get_lifetime_measure()->get_value() > 0.)
265 glog << " ; " << get_lifetime_measure();
266 if (is_isomer()) {
267 if (get_isomer_level() == 1)
268 glog << " [1rst isomer]";
269 else if (get_isomer_level() == 2)
270 glog << " [2nd isomer]";
271 else if (get_isomer_level() == 3)
272 glog << " [3rd isomer]";
273 else
274 glog << " [" << get_isomer_level() << "th isomer]";
275 }
276 if (is_uncertain()) {
277 glog << " uncertain level tag: " << funcertain_level;
278 }
279 glog << do_endl;
280
281 if (has_comment() && _option.contains("com")) {
282 const size_t comment_prefix_size = 13;
283 const size_t line_offset = comment_prefix_size + print_label_width + 1;
284 const std::string first_indent(line_offset - comment_prefix_size, ' ');
285 glog << comment << first_indent << wrap_text(get_comment(), line_offset, line_offset) << do_endl;
286 }
287 }
288}
289
290#ifdef HAS_ROOT
292ClassImp(tklevel);
293#endif
Represents a nuclear excited level (or ground state).
Definition tklevel.h:43
bool is_isomer()
returns true is the level an isomer
Definition tklevel.h:121
bool is_stable()
returns true if the level stable
Definition tklevel.h:119
double get_lifetime(const tkunit_manager::units_keys _unit=tkunit_manager::units_keys::s)
Definition tklevel.cpp:168
double get_mean_lifetime(tkunit_manager::units_keys _unit=tkunit_manager::s)
Mean lifetime tau = T1/2 / ln(2); time units only; same missing/stable rules.
Definition tklevel.cpp:158
shared_ptr< tkmeasure > get_lifetime_measure()
Legacy stored measure: half-life in time units, width in energy units.
Definition tklevel.h:85
const tkstring & get_comment()
get the level comment string
Definition tklevel.h:131
double get_energy(const tkunit_manager::units_keys _unit=tkunit_manager::units_keys::keV, bool _with_offset=false)
returns the energy in keV by default
Definition tklevel.cpp:136
void set_electric_quadrupole(tkdb_table::measure_data_struct &_struc)
define the level electric quadrupole moment
Definition tklevel.cpp:102
tkstring get_offset_bandhead()
returns the bandhead string offset value (ex: X)
Definition tklevel.h:82
shared_ptr< tkmeasure > get_energy_measure()
returns the energy tkmeasure object
Definition tklevel.h:75
void set_jpi(double _spin, int _parity, const tkstring &_jpi_str)
define the spin parity
Definition tklevel.cpp:119
void set_energy_offset(const tkstring &_offset)
define the energy offset
Definition tklevel.h:142
tklevel(int _id, const tkdb_table::measure_data_struct &_struc)
Definition tklevel.cpp:37
tkstring get_lifetime_str()
Legacy formatting of T1/2 or Gamma (not mean lifetime).
Definition tklevel.cpp:182
bool is_uncertain()
check if the level is uncertain
Definition tklevel.h:133
bool is_energy_offset()
to know if the energy is known with an energy offset
Definition tklevel.h:80
double get_decay_width(tkunit_manager::units_keys _unit=tkunit_manager::keV)
Decay width Gamma = hbar/tau; energy units only. Stable: 0; absent: NaN.
Definition tklevel.cpp:163
double get_electric_quadrupole()
return the electric quadrupole moment in barns
Definition tklevel.cpp:113
void print(const tkstring &_option="")
print the level properties
Definition tklevel.cpp:227
int get_isomer_level()
get the isomer level (1 for the ␌1rst (lowest energy) isomer, 2 for the second, etc....
Definition tklevel.h:123
bool is_yrast(bool _with_tentative=false)
returns true if the level is yrast
Definition tklevel.cpp:213
void set_lifetime(tkdb_table::measure_data_struct &_struc)
Define the stored ENSDF half-life (time) or width (energy).
Definition tklevel.cpp:58
double get_half_life(tkunit_manager::units_keys _unit=tkunit_manager::s)
Half-life T1/2; time units only. Stable: +inf; absent/invalid unit: NaN.
Definition tklevel.cpp:153
bool has_comment()
check if a comment exists
Definition tklevel.h:129
double get_magnetic_dipole()
return the magnetic dipole moment in nuclear magnetons
Definition tklevel.cpp:107
void set_magnetic_dipole(tkdb_table::measure_data_struct &_struc)
define the level magnetic dipole moment
Definition tklevel.cpp:97
Stores a physical measurement with its value, unit, and uncertainty.
Definition tkmeasure.h:56
void set_type(const tkstring &_type)
set the measured data type (energy, lifetime...)
Definition tkmeasure.h:103
bool has_property(const tkstring &_property) const
to check if the property is available
shared_ptr< tkmeasure > get(const tkstring &_property) const
get the property as tkmeasure
tkproperty_list(tkstring _name)
Nuclear excited state spin-parity.
std::string with usefull tricks from TString (ROOT) and KVString (KaliVeda) and more....
Definition tkstring.h:33
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
tkstring substr(size_type __pos=0, size_type __n=npos) const
Inlines.
Definition tkstring.h:160
bool contains(const char *_pat, ECaseCompare _cmp=kExact) const
Definition tkstring.h:184
units_keys
units identifiers
Definition tkunit.h:48
static const std::vector< std::tuple< tkstring, units_type, double > > funits_properties
Definition tkunit.h:54
double state_time_value(const shared_ptr< tkmeasure > &measure, bool stable, tkunit_manager::units_keys unit, bool width)
Definition tklog.cpp:16
std::string wrap_text(const tkstring &_text, size_t _first_content_col, size_t _continuation_col, size_t _max_line_width=80)
Definition tkstring.cpp:75
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
tklog & comment(tklog &log)
Definition tklog.h:319
data structure used to fill a tkmeasure object from the sqlite database
Definition tkdb_table.h:51