TkN 2.7
Toolkit for Nuclei
Loading...
Searching...
No Matches
tkmeasure.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 "tkmeasure.h"
15
16#include <algorithm>
17#include <limits>
18
19namespace tkn {
27}
28
29using namespace tkn;
30
31tkmeasure::tkmeasure(double _value, const tkunit_manager::units_keys &_unit, double _err)
32{
33 fValue.set_value(_value, _unit);
34 fError.set_value(_err, _unit);
35 fErrorLow.set_unit(_unit);
36 fErrorHigh.set_unit(_unit);
37}
38
39tkmeasure::tkmeasure(double _value, const tkunit_manager::units_keys &_unit, double _errlow, double _errhigh)
40{
41 fValue.set_value(_value, _unit);
42 fError.set_unit(_unit);
43 fErrorLow.set_value(_errlow, _unit);
44 fErrorHigh.set_value(_errhigh, _unit);
45
46 fAsymError = true;
47}
48
50{
51 finfo_tag = _tag;
52
53 if(_tag.is_empty()) return;
54 if(_tag.contains(";ERR=?")) {
56 finfo_tag.remove_all(";ERR=?");
57 }
58 if(_tag.contains(";ERR=CA")) {
60 finfo_tag.remove_all(";ERR=CA");
61 }
62 if(_tag.contains(";ERR=AP")) {
64 finfo_tag.remove_all(";ERR=AP");
65 }
66 if(_tag.contains(";ERR=SY")) {
68 finfo_tag.remove_all(";ERR=SY");
69 }
70 if(_tag.contains(";VAL=()")) {
72 finfo_tag.remove_all(";VAL=()");
73 }
74 if(_tag.contains(";ERR=LT") || _tag.contains(";ERR=GT") || _tag.contains(";ERR=LE") || _tag.contains(";ERR=GE")) {
76 }
77 if(_tag.contains(";ERR=CONV")) {
79 finfo_tag.remove_all(";ERR=CONV");
80 }
81}
82
83void tkmeasure::set(const double &_val, const tkstring &_unit)
84{
85 if(_unit != "" ) set_unit(_unit);
86 fValue.set_value(_val);
87}
88
89void tkmeasure::set(const double &_val, const tkunit_manager::units_keys &_unit)
90{
91 set_unit(_unit);
92 fValue.set_value(_val,_unit);
93}
94
96{
97 const auto old_unit = fValue.get_unit_key();
98 if (old_unit == _unit) return true;
99
100 const auto old_type = gunits->get_type(old_unit);
101 const auto new_type = gunits->get_type(_unit);
102 const bool cross_type = old_type != gunits->kUndef_type && old_type != new_type;
103
104 if (!cross_type) {
105 if (!fValue.set_unit(_unit)) return false;
106 fError.set_unit(_unit);
107 fErrorLow.set_unit(_unit);
108 fErrorHigh.set_unit(_unit);
109 return true;
110 }
111
112 // Energy/width <-> lifetime conversion is reciprocal, so uncertainty
113 // endpoints must be converted independently. Work on local copies and
114 // commit only after every conversion has succeeded.
115 tkunit converted_value = fValue;
116 if (!converted_value.set_unit(_unit)) return false;
117
118 const double error_low = fAsymError ? fErrorLow.get_value() : fError.get_value();
119 const double error_high = fAsymError ? fErrorHigh.get_value() : fError.get_value();
120
121 if (error_low < 0. || error_high < 0.) {
122 fValue = converted_value;
123 fError.set_value(-1., _unit);
124 fErrorLow.set_value(-1., _unit);
125 fErrorHigh.set_value(-1., _unit);
126 fAsymError = false;
127 return true;
128 }
129
130 const double value = fValue.get_value();
131 tkunit endpoint_low(value - error_low, old_unit);
132 tkunit endpoint_high(value + error_high, old_unit);
133 if (!endpoint_low.set_unit(_unit) || !endpoint_high.set_unit(_unit)) return false;
134
135 const double converted = converted_value.get_value();
136 const double converted_min = std::min(endpoint_low.get_value(), endpoint_high.get_value());
137 const double converted_max = std::max(endpoint_low.get_value(), endpoint_high.get_value());
138 const double converted_error_low = converted - converted_min;
139 const double converted_error_high = converted_max - converted;
140
141 fValue = converted_value;
142 if (converted_error_low == converted_error_high) {
143 fError.set_value(converted_error_low, _unit);
144 fErrorLow.set_value(-1., _unit);
145 fErrorHigh.set_value(-1., _unit);
146 fAsymError = false;
147 } else {
148 fError.set_value(-1., _unit);
149 fErrorLow.set_value(converted_error_low, _unit);
150 fErrorHigh.set_value(converted_error_high, _unit);
151 fAsymError = true;
152 }
153 return true;
154}
155
157{
158 if (get_unit_key() == _unit) return get_value();
159 tkmeasure converted = *this;
160 return converted.set_unit(_unit) ? converted.get_value() : std::numeric_limits<double>::quiet_NaN();
161}
162
164{
165 if(fAsymError) {
166 glog << warning_o << "The measure contains assymetric errors, the return value is the largest one" << do_endl;
167 return std::max(fErrorLow.get_value(),fErrorHigh.get_value());
168 }
169 return fError.get_value();
170}
171
173{
174 if (get_unit_key() == _unit) return get_error();
175 tkmeasure converted = *this;
176 return converted.set_unit(_unit) ? converted.get_error() : std::numeric_limits<double>::quiet_NaN();
177}
178
180{
181 if(!fAsymError) {
182 return fError.get_value();
183 }
184 return fErrorLow.get_value();
185}
186
188{
189 if (get_unit_key() == _unit) return get_error_low();
190 tkmeasure converted = *this;
191 return converted.set_unit(_unit) ? converted.get_error_low() : std::numeric_limits<double>::quiet_NaN();
192}
193
195{
196 if(!fAsymError) {
197 return fError.get_value();
198 }
199 return fErrorHigh.get_value();
200}
201
203{
204 if (get_unit_key() == _unit) return get_error_high();
205 tkmeasure converted = *this;
206 return converted.set_unit(_unit) ? converted.get_error_high() : std::numeric_limits<double>::quiet_NaN();
207}
208
209#ifdef HAS_ROOT
210ClassImp(tkmeasure);
211#endif
Stores a physical measurement with its value, unit, and uncertainty.
Definition tkmeasure.h:56
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
tkunit_manager::units_keys get_unit_key() const
returns the unit key
Definition tkmeasure.h:160
double get_value() const
returns the measure value
Definition tkmeasure.h:108
bool set_unit(const tkstring &_unit_name)
set the measured data unit (value and errors)
Definition tkmeasure.h:163
double get_error_low() const
returns the low assymetric error on the measured value
void set(const double &_val, const tkstring &_unit="")
set the measured value and unit. No given units keeps the current one
Definition tkmeasure.cpp:83
void set_info_tag(const tkstring &_tag)
define the info tag (calculation, systematic, approx value...)
Definition tkmeasure.cpp:49
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
std::string with usefull tricks from TString (ROOT) and KVString (KaliVeda) and more....
Definition tkstring.h:33
bool is_empty() const
Definition tkstring.h:145
bool contains(const char *_pat, ECaseCompare _cmp=kExact) const
Definition tkstring.h:184
units_keys
units identifiers
Definition tkunit.h:48
A measured value associated to its unit.
Definition tkunit.h:144
double get_value() const
get the value in the current unit
Definition tkunit.h:158
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:93
bool set_unit(const tkstring &_unit)
set the unit from a string
Definition tkunit.cpp:109
Definition tklog.cpp:16
tklog & warning_o(tklog &log)
Definition tklog.h:325
tklog & do_endl(tklog &log)
Definition tklog.h:212