TkN 2.4
Toolkit for Nuclei
Loading...
Searching...
No Matches
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 * Licensed under the MIT License <http://opensource.org/licenses/MIT>. *
11 * SPDX-License-Identifier: MIT *
12 ********************************************************************************/
13
14#ifndef tkmeasure_H
15#define tkmeasure_H
16
17
18#include <cmath>
19#include <iomanip>
20
21#include "tkn_config.h"
22#include "tklog.h"
23#include "tkproperty.h"
24#include "tkunit.h"
25
26#ifdef HAS_ROOT
27#include "TClass.h"
28#endif
29
30using namespace std;
31
32namespace tkn {
33
34typedef std::map<tkstring,pair<tkstring,tkstring>> properties; // map properties, value, unit
35
36class tkmeasure : public tkproperty
37{
38protected:
39
40 tkunit fValue{}; // the value of the measure
41 tkunit fError{}; // the error on this measure
42 tkunit fErrorLow{}; // if define, assym low error value
43 tkunit fErrorHigh{}; // if define, assym high error value
44
45 tkstring ftype=""; // type of measured data
46
47 bool fAsymError = false;
48
49 tkstring finfo_tag{}; // LT(<), GT(>), LE(<=), GE(>=), AP(~), CA (calculated), SY (from systematics), ? (uncertain, see comments), STABLE
50
51public:
53 tkmeasure(double _value, const tkstring &_unit_name, double _err = 0) : tkmeasure(_value, gunits->get_key(_unit_name), _err) {}
54 tkmeasure(double _value, const tkstring &_unit_name, double _errlow, double _errhigh) : tkmeasure(_value, gunits->get_key(_unit_name), _errlow, _errhigh) {}
55 tkmeasure(double _value, const tkunit_manager::units_keys &_unit, double _err = 0);
56 tkmeasure(double _value, const tkunit_manager::units_keys &_unit, double _errlow, double _errhigh);
57 virtual ~tkmeasure() override = default;
58
60 bool is_asym_errors() const { return fAsymError; }
61
63 void set_info_tag(const tkstring &_tag);
65 const tkstring &get_info_tag() {return finfo_tag;}
66 const tkstring &get_info_tag_const() const {return finfo_tag;}
67
69 void set_type(const tkstring &_type) {ftype = _type;}
71 const tkstring &get_type() const {return ftype;}
72
74 double get_value() const { return fValue.get_value();}
76 double get_value(const tkunit_manager::units_keys &_unit);
78 double get_value(const tkstring &_unit_name) {return get_value(gunits->get_key(_unit_name));}
79
81 void set(const double &_val, const tkstring &_unit="");
83 void set(const double &_val, const tkunit_manager::units_keys &_unit);
84
86 virtual void set_error(const double &_err) { fError.set_value(_err); fErrorLow.clear() ; fErrorHigh.clear() ; fAsymError = false;}
88 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; }
89
91 double get_error() const;
93 double get_error(const tkunit_manager::units_keys &_unit);
95 double get_error(const tkstring &_unit_name) {return get_error(gunits->get_key(_unit_name));}
96
98 double get_error_low() const;
100 double get_error_low(const tkunit_manager::units_keys &_unit);
102 double get_error_low(const tkstring &_unit_name) {return get_error_low(gunits->get_key(_unit_name));}
103
105 double get_error_high() const;
107 double get_error_high(const tkunit_manager::units_keys &_unit);
109 double get_error_high(const tkstring &_unit_name) {return get_error_high(gunits->get_key(_unit_name));}
110
112 tkstring get_unit() const { return fValue.get_unit_name();}
114 tkunit_manager::units_keys get_unit_key() const { return fValue.get_unit_key();}
115
117 bool set_unit(const tkstring &_unit_name) { return set_unit(gunits->get_key(_unit_name));}
119 bool set_unit(const tkunit_manager::units_keys &_unit);
120
122 friend std::ostream& operator<<(std::ostream& os, const tkmeasure *_measure) {
123
124 int save_precision = os.precision();
125 os << left << _measure->get_type();
126
127 //check energy offset
128 tkstring offset="";
129 if(_measure->get_info_tag_const().contains(";OFF=")) {
130 int idx = _measure->get_info_tag_const().index(";OFF=");
131 offset = _measure->get_info_tag_const().substr(idx+5,1) + "+";
132 }
133
134 if(_measure->is_info(kLimit)) {
135 if(_measure->get_info_tag_const().contains(";ERR=LT")) os << " < ";
136 else if(_measure->get_info_tag_const().contains(";ERR=LE")) os << " <= ";
137 else if(_measure->get_info_tag_const().contains(";ERR=GT")) os << " > ";
138 else if(_measure->get_info_tag_const().contains(";ERR=GE")) os << " >= ";
139 }
140 else if(_measure->is_info(kAbout)) os << " ~ ";
141 else os << " = ";
142
143 if(!_measure->get_info_tag_const().empty() && _measure->get_info_tag_const().contains("STABLE")) {
144 os << left << std::setw(7) << "STABLE" << std::setw(9) << "";
145 }
146 else {
147 if(_measure->is_asym_errors() && _measure->get_error_low()>0 && _measure->get_error_high()>0) {
148 int exp_error_low = _measure->get_exp_error_precision(_measure->get_error_low());
149 int exp_error_high = _measure->get_exp_error_precision(_measure->get_error_high());
150 int exp_error = max(max(exp_error_low,exp_error_high),_measure->get_exp_error_precision(_measure->get_value()));
151
152 if(_measure->get_value() !=0 && (_measure->get_value()>1e5 || _measure->get_value()<1e-5)) os << scientific;
153 else os << fixed;
154
155 os << left << setprecision(exp_error) << offset << std::setw(7) << _measure->get_value();
156 os << " (-"<< std::setw(5) << _measure->get_error_low() << " ; +" << std::setw(5) << _measure->get_error_high() <<") " << _measure->get_unit();
157 }
158 else {
159 int exp_error = max(_measure->get_exp_error_precision(_measure->get_value()),_measure->get_exp_error_precision(_measure->get_error()));
160 if(_measure->get_value() !=0 && (abs(_measure->get_value())>1e5 || abs(_measure->get_value())<1e-5)) os << scientific;
161 else os << fixed;
162
163 if(_measure->get_error()>0.) {
164 os << left << setprecision(exp_error) << offset << std::setw(7) << _measure->get_value();
165 os << " ("<< std::setw(5) << _measure->get_error() << ") " << _measure->get_unit();
166 }
167 else if(_measure->get_error()==0.) {
168 os << left << setprecision(_measure->get_exp_error_precision(_measure->get_value())) << offset << std::setw(7) << _measure->get_value();
169 os << _measure->get_unit();
170 }
171 else {
172 os << left << setprecision(_measure->get_exp_error_precision(_measure->get_value())) << offset << std::setw(7) << _measure->get_value();
173 if(_measure->get_value()==0.) os << " "<< std::setw(5) << " " << " " << _measure->get_unit();
174 else os << fixed << left << setprecision(exp_error) << " ("<< std::setw(5) << " ? " << ") " << _measure->get_unit();
175 }
176 }
177 }
178
179 if(!_measure->is_info(kKnown) || _measure->is_converted()) {
180 os << " ["<< _measure->get_info_str(false) << "]";
181 }
182
183 os.precision(save_precision);
184
185 return os;
186 }
187
189 void print(bool with_return=true) {cout<<(this);
190 if(with_return) cout<<endl;}
191
192 tkmeasure operator+(const tkmeasure& _measure) const{
193 tkmeasure result = *this;
194 tkmeasure measure_to_add = _measure;
195 if(this->get_unit() != measure_to_add.get_unit()) {
196 if(!measure_to_add.set_unit(get_unit())) {
197 glog << warning_o << "trying to add two different types of units... ignored" << do_endl;
198 return result;
199 }
200 }
201 result.set(this->get_value() + measure_to_add.get_value());
202 double low_e1, high_e1, low_e2, high_e2;
203 if(is_asym_errors()) {
204 low_e1 = get_error_low();
205 high_e1 = get_error_high();
206 }
207 else {
208 low_e1 = get_error();
209 high_e1 = get_error();
210 }
211 if(measure_to_add.is_asym_errors()) {
212 low_e2 = measure_to_add.get_error_low();
213 high_e2 = measure_to_add.get_error_high();
214 }
215 else {
216 low_e2 = measure_to_add.get_error();
217 high_e2 = measure_to_add.get_error();
218 }
219 if(is_asym_errors() || measure_to_add.is_asym_errors()) {
220 result.set_error(sqrt(low_e1*low_e1+low_e2*low_e2),sqrt(high_e1*high_e1+high_e2*high_e2));
221 }
222 else result.set_error(sqrt(low_e1*low_e1+low_e2*low_e2));
223
224 if(get_info_const() != kKnown || measure_to_add.get_info() != kKnown) {
225 if(get_info_const() == kKnown && measure_to_add.get_info() != kKnown) result.set_info(measure_to_add.get_info());
226 else if(get_info_const() != kKnown && measure_to_add.get_info() == kKnown) result.set_info(get_info_const());
227 if(get_info_const() != kKnown && measure_to_add.get_info() != kKnown) result.set_info(kUncertain);
228
229 result.set_info_tag(get_info_tag_const()+measure_to_add.get_info_tag());
230 if(measure_to_add.is_converted()) result.set_converted();
231 }
232 return result;
233 }
234 tkmeasure operator*(double _multiplier) const{
235 tkmeasure result = *this;
236 result.set(get_value()*_multiplier);
237 double low_e1, high_e1;
238 if(is_asym_errors()) {
239 if(_multiplier<0) {
240 low_e1 = get_error_high()*_multiplier;
241 high_e1 = get_error_low()*_multiplier;
242 }
243 else {
244 low_e1 = get_error_low()*_multiplier;
245 high_e1 = get_error_high()*_multiplier;
246 }
247 }
248 else {
249 low_e1 = get_error()*_multiplier;
250 high_e1 = get_error()*_multiplier;
251 }
252 if(is_asym_errors()) result.set_error(low_e1,high_e1);
253 else result.set_error(low_e1);
254
255 if(_multiplier<0) {
256 if(result.get_info_tag().contains("LT")) result.set_info_tag(result.get_info_tag().copy().replace_all("LT","GT"));
257 if(result.get_info_tag().contains("LE")) result.set_info_tag(result.get_info_tag().copy().replace_all("LE","GE"));
258 if(result.get_info_tag().contains("GT")) result.set_info_tag(result.get_info_tag().copy().replace_all("GT","LT"));
259 }
260 return result;
261 }
262 friend tkmeasure operator*(double _multiplier, const tkmeasure & obj) {return obj * _multiplier;}
264 tkmeasure result = *this * -1.;
265 return result;
266 }
267 tkmeasure operator-(const tkmeasure& _measure) const {
268 tkmeasure measure_to_add = -_measure;
269 tkmeasure result = *this + measure_to_add;
270 return result;
271 }
272
274 int get_exp_error_precision(const double &_err) const {
275 double precision_float_error = tkstring::get_precision(tkstring::Form("%g",_err));
276 if(_err<0.) precision_float_error = tkstring::get_precision(tkstring::Form("%g",get_value()));
277 int precision_int_err = (int) precision_float_error;
278 if(precision_float_error<1) precision_int_err = (int) (-(1./precision_float_error+0.5));
279
280 int exp_error = (int)std::floor(std::log10(std::fabs(precision_int_err) ) );
281 if(precision_int_err >= 0) exp_error = 0 ;
282 return exp_error;
283 }
284
285#ifdef HAS_ROOT
287 ClassDefOverride(tkmeasure,0);
288#endif
289
290};
291}
292
293#endif
Stores information on an experimental measure.
Definition tkmeasure.h:37
const tkstring & get_info_tag()
returns the info tag (calculation, systematic, approx value...)
Definition tkmeasure.h:65
tkmeasure operator-() const
Definition tkmeasure.h:263
void print(bool with_return=true)
print the measured properties
Definition tkmeasure.h:189
const tkstring & get_type() const
returns the measured data type (energy, lifetime...)
Definition tkmeasure.h:71
double get_error() const
returns the error on the measured value
double get_error_high() const
returns the high assymetric error on the measured value
friend std::ostream & operator<<(std::ostream &os, const tkmeasure *_measure)
redefinition of the << operator to take precision into account
Definition tkmeasure.h:122
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:109
tkstring get_unit() const
returns the unit name
Definition tkmeasure.h:112
void set_type(const tkstring &_type)
set the measured data type (energy, lifetime...)
Definition tkmeasure.h:69
virtual ~tkmeasure() override=default
tkunit_manager::units_keys get_unit_key() const
returns the unit key
Definition tkmeasure.h:114
double get_value(const tkstring &_unit_name)
returns the measure value in the required string unit
Definition tkmeasure.h:78
tkmeasure(double _value, const tkstring &_unit_name, double _errlow, double _errhigh)
Definition tkmeasure.h:54
bool is_asym_errors() const
test is the measure uncertainty is asymmetric
Definition tkmeasure.h:60
virtual void set_error(const double &_err)
set the error of this measured data
Definition tkmeasure.h:86
friend tkmeasure operator*(double _multiplier, const tkmeasure &obj)
Definition tkmeasure.h:262
const tkstring & get_info_tag_const() const
Definition tkmeasure.h:66
double get_error(const tkstring &_unit_name)
returns the error on the measured value in the required string unit
Definition tkmeasure.h:95
tkmeasure(double _value, const tkstring &_unit_name, double _err=0)
Definition tkmeasure.h:53
tkmeasure operator+(const tkmeasure &_measure) const
Definition tkmeasure.h:192
double get_value() const
returns the measure value
Definition tkmeasure.h:74
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:102
bool set_unit(const tkstring &_unit_name)
set the measured data unit (value and errors)
Definition tkmeasure.h:117
double get_error_low() const
returns the low assymetric error on the measured value
virtual void set_error(const double &_err_low, const double &_err_high)
set the asymetruic error of this value
Definition tkmeasure.h:88
int get_exp_error_precision(const double &_err) const
calculate the needed precision for printouts
Definition tkmeasure.h:274
void set(const double &_val, const tkstring &_unit="")
set the measured value and unit. No given units keeps the current one
tkmeasure operator*(double _multiplier) const
Definition tkmeasure.h:234
tkmeasure operator-(const tkmeasure &_measure) const
Definition tkmeasure.h:267
void set_info_tag(const tkstring &_tag)
define the info tag (calculation, systematic, approx value...)
bool is_converted() const
to know if the value has been converted
Definition tkproperty.h:52
void set_info(tkproperty::data_info _info)
to set some information about this data
Definition tkproperty.h:55
void set_converted(bool _val=true)
to define the value as a converted one
Definition tkproperty.h:49
data_info get_info_const() const
Definition tkproperty.h:59
tkstring get_info_str(bool _showknown=true) const
to print in string the data_info
data_info get_info()
to get information about this data
Definition tkproperty.h:58
bool is_info(data_info _info) const
to get some information about this data
Definition tkproperty.h:65
std::string with usefull tricks from TString (ROOT) and KVString (KaliVeda) and more....
Definition tkstring.h:31
tkstring copy() const
Returns a copy of this string.
Definition tkstring.cpp:347
static tkstring Form(const char *_format,...)
Definition tkstring.cpp:322
tkstring substr(size_type __pos=0, size_type __n=npos) const
Inlines.
Definition tkstring.h:156
size_t index(const char *_s, size_t _pos=0, ECaseCompare _cmp=kExact) const
Returns the index of the substring _s.
Definition tkstring.cpp:195
bool contains(const char *_pat, ECaseCompare _cmp=kExact) const
Definition tkstring.h:174
static double get_precision(tkstring _st)
Extract the precision for a given ENSDF data.
Definition tkstring.cpp:626
tkstring & replace_all(const tkstring &_s1, const tkstring &_s2)
Definition tkstring.h:180
units_keys
units identifiers
Definition tkunit.h:46
A measured value associated to its unit.
Definition tkunit.h:120
Definition tklog.cpp:16
tklog & warning_o(tklog &log)
Definition tklog.h:325
std::map< tkstring, pair< tkstring, tkstring > > properties
Definition tkmeasure.h:34
tklog & do_endl(tklog &log)
Definition tklog.h:212