TkN 2.1
Toolkit for Nuclei
tkmeasure.h
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 * This software is governed by the CeCILL-B license under French law and *
11 * abiding by the rules of distribution of free software. You can use, *
12 * modify and/ or redistribute the software under the terms of the *
13 * CeCILL-B license as circulated by CEA, CNRS and INRIA at the following *
14 * URL \"http://www.cecill.info\". *
15 * *
16 * As a counterpart to the access to the source code and rights to copy, *
17 * modify and redistribute granted by the license, users are provided *
18 * only with a limited warranty and the software's author, the holder of *
19 * the economic rights, and the successive licensors have only limited *
20 * liability. *
21 * *
22 * In this respect, the user's attention is drawn to the risks associated *
23 * with loading, using, modifying and/or developing or reproducing the *
24 * software by the user in light of its specific status of free software, *
25 * that may mean that it is complicated to manipulate, and that also *
26 * therefore means that it is reserved for developers and experienced *
27 * professionals having in-depth computer knowledge. Users are therefore *
28 * encouraged to load and test the software's suitability as regards *
29 * their requirements in conditions enabling the security of their *
30 * systems and/or data to be ensured and, more generally, to use and *
31 * operate it in the same conditions as regards security. *
32 * *
33 * The fact that you are presently reading this means that you have had *
34 * knowledge of the CeCILL-B license and that you accept its terms. *
35 ********************************************************************************/
36
37#ifndef tkmeasure_H
38#define tkmeasure_H
39
40
41#include <cmath>
42#include <iomanip>
43
44#include "tkn_config.h"
45#include "tklog.h"
46#include "tkproperty.h"
47#include "tkunit.h"
48
49#ifdef HAS_ROOT
50#include "TClass.h"
51#endif
52
53using namespace std;
54
55namespace tkn {
56
57typedef std::map<tkstring,pair<tkstring,tkstring>> properties; // map properties, value, unit
58
59class tkmeasure : public tkproperty
60{
61protected:
62
63 tkunit fValue{}; // the value of the measure
64 tkunit fError{}; // the error on this measure
65 tkunit fErrorLow{}; // if define, assym low error value
66 tkunit fErrorHigh{}; // if define, assym high error value
67
68 tkstring ftype=""; // type of measured data
69
70 bool fAsymError = false;
71
72 tkstring finfo_tag{}; // LT(<), GT(>), LE(<=), GE(>=), AP(~), CA (calculated), SY (from systematics), ? (uncertain, see comments), STABLE
73
74public:
76 tkmeasure(double _value, const tkstring &_unit_name, double _err = 0) : tkmeasure(_value, gunits->get_key(_unit_name), _err) {}
77 tkmeasure(double _value, const tkstring &_unit_name, double _errlow, double _errhigh) : tkmeasure(_value, gunits->get_key(_unit_name), _errlow, _errhigh) {}
78 tkmeasure(double _value, const tkunit_manager::units_keys &_unit, double _err = 0);
79 tkmeasure(double _value, const tkunit_manager::units_keys &_unit, double _errlow, double _errhigh);
80 virtual ~tkmeasure() = default;
81
83 bool is_asym_errors() const { return fAsymError; }
84
86 void set_info_tag(const tkstring &_tag);
88 const tkstring &get_info_tag() {return finfo_tag;}
89 const tkstring &get_info_tag_const() const {return finfo_tag;}
90
92 void set_type(const tkstring &_type) {ftype = _type;}
94 const tkstring &get_type() const {return ftype;}
95
97 double get_value() const { return fValue.get_value();}
99 double get_value(const tkunit_manager::units_keys &_unit);
101 double get_value(const tkstring &_unit_name) {return get_value(gunits->get_key(_unit_name));}
102
104 void set(const double &_val, const tkstring &_unit="");
106 void set(const double &_val, const tkunit_manager::units_keys &_unit);
107
109 virtual void set_error(const double &_err) { fError.set_value(_err); fErrorLow.clear() ; fErrorHigh.clear() ; fAsymError = false;}
111 virtual void set_error(const double &_err_low, const double &_err_high) { fErrorLow.set_value(_err_low); fErrorHigh.set_value(_err_high) ; fError.clear(); fAsymError = true; }
112
114 double get_error() const;
116 double get_error(const tkunit_manager::units_keys &_unit);
118 double get_error(const tkstring &_unit_name) {return get_error(gunits->get_key(_unit_name));}
119
121 double get_error_low() const;
123 double get_error_low(const tkunit_manager::units_keys &_unit);
125 double get_error_low(const tkstring &_unit_name) {return get_error_low(gunits->get_key(_unit_name));}
126
128 double get_error_high() const;
130 double get_error_high(const tkunit_manager::units_keys &_unit);
132 double get_error_high(const tkstring &_unit_name) {return get_error_high(gunits->get_key(_unit_name));}
133
135 tkstring get_unit() const { return fValue.get_unit_name();}
138
140 bool set_unit(const tkstring &_unit_name) { return set_unit(gunits->get_key(_unit_name));}
142 bool set_unit(const tkunit_manager::units_keys &_unit);
143
145 friend std::ostream& operator<<(std::ostream& os, const tkmeasure *_measure) {
146
147 int save_precision = os.precision();
148 os << left << _measure->get_type();
149
150 //check energy offset
151 tkstring offset="";
152 if(_measure->get_info_tag_const().contains(";OFF=")) {
153 int idx = _measure->get_info_tag_const().index(";OFF=");
154 offset = _measure->get_info_tag_const().substr(idx+5,1) + "+";
155 }
156
157 if(_measure->is_info(kLimit)) {
158 if(_measure->get_info_tag_const().contains(";ERR=LT")) os << " < ";
159 else if(_measure->get_info_tag_const().contains(";ERR=LE")) os << " <= ";
160 else if(_measure->get_info_tag_const().contains(";ERR=GT")) os << " > ";
161 else if(_measure->get_info_tag_const().contains(";ERR=GE")) os << " >= ";
162 }
163 else if(_measure->is_info(kAbout)) os << " ~ ";
164 else os << " = ";
165
166 if(!_measure->get_info_tag_const().empty() && _measure->get_info_tag_const().contains("STABLE")) {
167 os << left << std::setw(7) << "STABLE" << std::setw(9) << "";
168 }
169 else {
170 if(_measure->is_asym_errors() && _measure->get_error_low()>0 && _measure->get_error_high()>0) {
171 int exp_error_low = _measure->get_exp_error_precision(_measure->get_error_low());
172 int exp_error_high = _measure->get_exp_error_precision(_measure->get_error_high());
173 int exp_error = max(max(exp_error_low,exp_error_high),_measure->get_exp_error_precision(_measure->get_value()));
174
175 if(_measure->get_value() !=0 && (_measure->get_value()>1e5 || _measure->get_value()<1e-5)) os << scientific;
176 else os << fixed;
177
178 os << left << setprecision(exp_error) << offset << std::setw(7) << _measure->get_value();
179 os << " (-"<< std::setw(5) << _measure->get_error_low() << " ; +" << std::setw(5) << _measure->get_error_high() <<") " << _measure->get_unit();
180 }
181 else {
182 int exp_error = max(_measure->get_exp_error_precision(_measure->get_value()),_measure->get_exp_error_precision(_measure->get_error()));
183 if(_measure->get_value() !=0 && (abs(_measure->get_value())>1e5 || abs(_measure->get_value())<1e-5)) os << scientific;
184 else os << fixed;
185
186 if(_measure->get_error()>0.) {
187 os << left << setprecision(exp_error) << offset << std::setw(7) << _measure->get_value();
188 os << " ("<< std::setw(5) << _measure->get_error() << ") " << _measure->get_unit();
189 }
190 else if(_measure->get_error()==0.) {
191 os << left << setprecision(_measure->get_exp_error_precision(_measure->get_value())) << offset << std::setw(7) << _measure->get_value();
192 os << _measure->get_unit();
193 }
194 else {
195 os << left << setprecision(_measure->get_exp_error_precision(_measure->get_value())) << offset << std::setw(7) << _measure->get_value();
196 if(_measure->get_value()==0.) os << " "<< std::setw(5) << " " << " " << _measure->get_unit();
197 else os << fixed << left << setprecision(exp_error) << " ("<< std::setw(5) << " ? " << ") " << _measure->get_unit();
198 }
199 }
200 }
201
202 if(!_measure->is_info(kKnown) || _measure->is_converted()) {
203 os << " ["<< _measure->get_info_str(false) << "]";
204 }
205
206 os.precision(save_precision);
207
208 return os;
209 }
210
212 void print(bool with_return=true) {cout<<(this);
213 if(with_return) cout<<endl;}
214
215 tkmeasure operator+(const tkmeasure& _measure) const{
216 tkmeasure result = *this;
217 tkmeasure measure_to_add = _measure;
218 if(this->get_unit() != measure_to_add.get_unit()) {
219 if(!measure_to_add.set_unit(get_unit())) {
220 glog << warning_o << "trying to add two different types of units... ignored" << do_endl;
221 return result;
222 }
223 }
224 result.set(this->get_value() + measure_to_add.get_value());
225 double low_e1, high_e1, low_e2, high_e2;
226 if(is_asym_errors()) {
227 low_e1 = get_error_low();
228 high_e1 = get_error_high();
229 }
230 else {
231 low_e1 = get_error();
232 high_e1 = get_error();
233 }
234 if(measure_to_add.is_asym_errors()) {
235 low_e2 = measure_to_add.get_error_low();
236 high_e2 = measure_to_add.get_error_high();
237 }
238 else {
239 low_e2 = measure_to_add.get_error();
240 high_e2 = measure_to_add.get_error();
241 }
242 if(is_asym_errors() || measure_to_add.is_asym_errors()) {
243 result.set_error(sqrt(low_e1*low_e1+low_e2*low_e2),sqrt(high_e1*high_e1+high_e2*high_e2));
244 }
245 else result.set_error(sqrt(low_e1*low_e1+low_e2*low_e2));
246
247 if(get_info_const() != kKnown && measure_to_add.get_info() != kKnown) {
248 if(get_info_const() == kKnown && measure_to_add.get_info() != kKnown) result.set_info(measure_to_add.get_info());
249 if(get_info_const() != kKnown && measure_to_add.get_info() != kKnown) result.set_info(kUncertain);
250
251 result.set_info_tag(get_info_tag_const()+measure_to_add.get_info_tag());
252 if(measure_to_add.is_converted()) result.set_converted();
253 }
254 return result;
255 }
256 tkmeasure operator*(double _multiplier) const{
257 tkmeasure result = *this;
258 result.set(get_value()*_multiplier);
259 double low_e1, high_e1;
260 if(is_asym_errors()) {
261 if(_multiplier<0) {
262 low_e1 = get_error_high()*_multiplier;
263 high_e1 = get_error_low()*_multiplier;
264 }
265 else {
266 low_e1 = get_error_low()*_multiplier;
267 high_e1 = get_error_high()*_multiplier;
268 }
269 }
270 else {
271 low_e1 = get_error()*_multiplier;
272 high_e1 = get_error()*_multiplier;
273 }
274 if(is_asym_errors()) result.set_error(low_e1,high_e1);
275 else result.set_error(low_e1);
276
277 if(_multiplier<0) {
278 if(result.get_info_tag().contains("LT")) result.set_info_tag(result.get_info_tag().copy().replace_all("LT","GT"));
279 if(result.get_info_tag().contains("LE")) result.set_info_tag(result.get_info_tag().copy().replace_all("LE","GE"));
280 if(result.get_info_tag().contains("GT")) result.set_info_tag(result.get_info_tag().copy().replace_all("GT","LT"));
281 }
282 return result;
283 }
284 friend tkmeasure operator*(double _multiplier, const tkmeasure & obj) {return obj * _multiplier;}
286 tkmeasure result = *this * -1.;
287 return result;
288 }
289 tkmeasure operator-(const tkmeasure& _measure) const {
290 tkmeasure measure_to_add = -_measure;
291 tkmeasure result = *this + measure_to_add;
292 return result;
293 }
294
296 int get_exp_error_precision(const double &_err) const {
297 double precision_float_error = tkstring::get_precision(tkstring::Form("%g",_err));
298 if(_err<0.) precision_float_error = tkstring::get_precision(tkstring::Form("%g",get_value()));
299 int precision_int_err = (int) precision_float_error;
300 if(precision_float_error<1) precision_int_err = (int) (-(1./precision_float_error+0.5));
301
302 int exp_error = (int)std::floor(std::log10(std::fabs(precision_int_err) ) );
303 if(precision_int_err >= 0) exp_error = 0 ;
304 return exp_error;
305 }
306
307#ifdef HAS_ROOT
309 ClassDef(tkmeasure,0);
310#endif
311
312};
313}
314
315#endif
Stores information on an experimental measure.
Definition: tkmeasure.h:60
const tkstring & get_info_tag()
returns the info tag (calculation, systematic, approx value...)
Definition: tkmeasure.h:88
tkmeasure operator-() const
Definition: tkmeasure.h:285
void print(bool with_return=true)
print the measured properties
Definition: tkmeasure.h:212
const tkstring & get_type() const
returns the measured data type (energy, lifetime...)
Definition: tkmeasure.h:94
double get_error() const
returns the error on the measured value
Definition: tkmeasure.cpp:174
double get_error_high() const
returns the high assymetric error on the measured value
Definition: tkmeasure.cpp:209
friend std::ostream & operator<<(std::ostream &os, const tkmeasure *_measure)
redefinition of the << operator to take precision into account
Definition: tkmeasure.h:145
double get_error_high(const tkstring &_unit_name)
returns the high assymetric error on the measured value in the required string unit
Definition: tkmeasure.h:132
tkstring get_unit() const
returns the unit name
Definition: tkmeasure.h:135
void set_type(const tkstring &_type)
set the measured data type (energy, lifetime...)
Definition: tkmeasure.h:92
tkunit_manager::units_keys get_unit_key() const
returns the unit key
Definition: tkmeasure.h:137
double get_value(const tkstring &_unit_name)
returns the measure value in the required string unit
Definition: tkmeasure.h:101
tkmeasure(double _value, const tkstring &_unit_name, double _errlow, double _errhigh)
Definition: tkmeasure.h:77
bool is_asym_errors() const
test is the measure uncertainty is asymmetric
Definition: tkmeasure.h:83
virtual void set_error(const double &_err)
set the error of this measured data
Definition: tkmeasure.h:109
friend tkmeasure operator*(double _multiplier, const tkmeasure &obj)
Definition: tkmeasure.h:284
const tkstring & get_info_tag_const() const
Definition: tkmeasure.h:89
double get_error(const tkstring &_unit_name)
returns the error on the measured value in the required string unit
Definition: tkmeasure.h:118
tkmeasure(double _value, const tkstring &_unit_name, double _err=0)
Definition: tkmeasure.h:76
tkmeasure operator+(const tkmeasure &_measure) const
Definition: tkmeasure.h:215
double get_value() const
returns the measure value
Definition: tkmeasure.h:97
double get_error_low(const tkstring &_unit_name)
returns the low assymetric error on the measured value in the required string unit
Definition: tkmeasure.h:125
bool set_unit(const tkstring &_unit_name)
set the measured data unit (value and errors)
Definition: tkmeasure.h:140
double get_error_low() const
returns the low assymetric error on the measured value
Definition: tkmeasure.cpp:192
virtual void set_error(const double &_err_low, const double &_err_high)
set the asymetruic error of this value
Definition: tkmeasure.h:111
int get_exp_error_precision(const double &_err) const
calculate the needed precision for printouts
Definition: tkmeasure.h:296
void set(const double &_val, const tkstring &_unit="")
set the measured value and unit. No given units keeps the current one
Definition: tkmeasure.cpp:103
tkmeasure operator*(double _multiplier) const
Definition: tkmeasure.h:256
tkmeasure operator-(const tkmeasure &_measure) const
Definition: tkmeasure.h:289
virtual ~tkmeasure()=default
void set_info_tag(const tkstring &_tag)
define the info tag (calculation, systematic, approx value...)
Definition: tkmeasure.cpp:69
Any property (data) with flags.
Definition: tkproperty.h:51
bool is_converted() const
to know if the value has been converted
Definition: tkproperty.h:75
void set_info(tkproperty::data_info _info)
to set some information about this data
Definition: tkproperty.h:78
void set_converted(bool _val=true)
to define the value as a converted one
Definition: tkproperty.h:72
data_info get_info_const() const
Definition: tkproperty.h:82
tkstring get_info_str(bool _showknown=true) const
to print in string the data_info
Definition: tkproperty.cpp:93
data_info get_info()
to get information about this data
Definition: tkproperty.h:81
bool is_info(data_info _info) const
to get some information about this data
Definition: tkproperty.h:88
std::string with usefull tricks from TString (ROOT) and KVString (KaliVeda) and more....
Definition: tkstring.h:54
tkstring copy() const
Returns a copy of this string.
Definition: tkstring.cpp:370
static tkstring Form(const char *_format,...)
Definition: tkstring.cpp:345
tkstring substr(size_type __pos=0, size_type __n=npos) const
Inlines.
Definition: tkstring.h:179
size_t index(const char *_s, size_t _pos=0, ECaseCompare _cmp=kExact) const
Returns the index of the substring _s.
Definition: tkstring.cpp:218
bool contains(const char *_pat, ECaseCompare _cmp=kExact) const
Definition: tkstring.h:197
static double get_precision(tkstring _st)
Extract the precision for a given ENSDF data.
Definition: tkstring.cpp:649
tkstring & replace_all(const tkstring &_s1, const tkstring &_s2)
Definition: tkstring.h:203
units_keys
units identifiers
Definition: tkunit.h:69
A measured value associated to its unit.
Definition: tkunit.h:143
tkunit_manager::units_keys get_unit_key() const
returns the unit key
Definition: tkunit.h:172
double get_value() const
get the value in the current unit
Definition: tkunit.h:157
void set_value(const double &_val, const tkstring &_unit="")
set the value and unit from string, if _unit not defined, let in the current unit
Definition: tkunit.cpp:122
tkstring get_unit_name() const
returns the unit name
Definition: tkunit.h:170
void clear()
reset the data_unit
Definition: tkunit.h:175
Definition: tklog.cpp:39
tklog & warning_o(tklog &log)
Definition: tklog.h:348
std::map< tkstring, pair< tkstring, tkstring > > properties
Definition: tkmeasure.h:57
tklog & do_endl(tklog &log)
Definition: tklog.h:235