REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestSystemOfUnits.cxx
1#include <iostream>
2#include <limits>
3
4#include "TRestStringHelper.h"
5
6using namespace std;
7
8namespace REST_Units {
9struct UnitsStruct {
10 UnitsStruct() {
11 name = "";
12 type = -1;
13 scale = 1;
14 }
15 UnitsStruct(string _name, int _type, double _scale) {
16 name = _name;
17 type = _type;
18 scale = _scale;
19 }
20
21 string name = "";
22 int type = -1;
23 double scale = 1;
24
25 bool operator>(const UnitsStruct& compare) const { return name > compare.name; }
26
27 bool operator<(const UnitsStruct& compare) const { return name < compare.name; }
28
29 bool operator==(const UnitsStruct& compare) const { return name == compare.name; }
30};
31
32map<string, pair<int, double>> __ListOfRESTUnits; // name, {type, scale}
33} // namespace REST_Units
34#define REST_UnitsAdd_Caller
35
36#include "TRestSystemOfUnits.h"
37
54namespace REST_Units {
55
65bool IsUnit(string unitsStr) { return !TRestSystemOfUnits(unitsStr).IsZombie(); }
66
70bool IsBasicUnit(string unitsStr) { return (__ListOfRESTUnits.count(unitsStr) == 1); }
71
76double GetScaleToStandardUnit(string unitsdef) { return 1 * TRestSystemOfUnits(unitsdef); }
77
82string GetStandardUnitDefinition(string unitsdef) { return units(unitsdef).ToStandardDefinition(); }
83
94string FindRESTUnitsInString(string s) {
95 size_t l = RemoveUnitsFromString(s).length();
96 string unitDef = s.substr(l, -1);
97
98 if (IsUnit(unitDef)) {
99 return unitDef;
100 }
101 return "";
102}
103
115string RemoveUnitsFromString(string s) {
116 string valstr1 = s.substr(0, s.find_first_not_of("1234567890(),.-eE/: "));
117
118 if (valstr1.size() == 0) {
119 return "";
120 }
121
122 // if e turns out to be the last character, we shall also strip it
123 if (valstr1[valstr1.size() - 1] == 'e' || valstr1[valstr1.size() - 1] == 'E') {
124 return valstr1.substr(0, valstr1.size() - 1);
125 }
126
127 return valstr1;
128}
129
135Double_t GetDblValueInString(string in) {
136 string units = FindRESTUnitsInString(in);
137 double val = StringToDouble(RemoveUnitsFromString(in));
138 return ConvertValueToRESTUnits(val, units);
139}
140
146Double_t GetValueInRESTUnits(string in) { return GetDblValueInString(in); }
147
153Double_t GetDblValueInRESTUnits(string in) { return GetDblValueInString(in); }
154
160TVector2 Get2DVectorValueInString(string in) {
161 string unit = FindRESTUnitsInString(in);
162 TVector2 value = StringTo2DVector(RemoveUnitsFromString(in));
163 Double_t valueX = REST_Units::ConvertValueToRESTUnits(value.X(), unit);
164 Double_t valueY = REST_Units::ConvertValueToRESTUnits(value.Y(), unit);
165 return TVector2(valueX, valueY);
166}
167
173TVector2 Get2DVectorInRESTUnits(string in) { return Get2DVectorValueInString(in); }
174
180TVector3 Get3DVectorValueInString(string in) {
181 string unit = FindRESTUnitsInString(in);
182 TVector3 value = StringTo3DVector(RemoveUnitsFromString(in));
183 Double_t valueX = REST_Units::ConvertValueToRESTUnits(value.X(), unit);
184 Double_t valueY = REST_Units::ConvertValueToRESTUnits(value.Y(), unit);
185 Double_t valueZ = REST_Units::ConvertValueToRESTUnits(value.Z(), unit);
186 return TVector3(valueX, valueY, valueZ);
187}
188
194TVector3 Get3DVectorInRESTUnits(string in) { return Get3DVectorValueInString(in); }
195
211Double_t ConvertValueToRESTUnits(Double_t value, string unitsStr) {
212 return value / TRestSystemOfUnits((string)unitsStr);
213}
214
218Double_t ConvertRESTUnitsValueToCustomUnits(Double_t value, string unitsStr) {
219 return value * TRestSystemOfUnits((string)unitsStr);
220}
221
227double _AddUnit(string name, int type, double scale) {
228 __ListOfRESTUnits[name] = {type, scale};
229 return scale;
230}
231
253 unitsStr = Trim(unitsStr);
254
255 // We skip for the moment parameters/fields that contain elements {,,,}.
256 if (unitsStr.find("{") != string::npos || unitsStr.find("}") != string::npos) {
257 fZombie = true;
258 return;
259 }
260
261 if (unitsStr == "") {
262 fZombie = true;
263 return;
264 }
265 fScaleCombined = 1;
266
267 for (size_t pos = 0; pos >= 0 && pos < unitsStr.size();) {
268 if (isalpha(unitsStr[pos])) {
269 size_t pos1 = pos;
270 while (pos < unitsStr.size() && isalpha(unitsStr[pos])) {
271 pos++;
272 }
273 size_t pos2 = pos;
274 string singleunit = unitsStr.substr(pos1, pos2 - pos1);
275
276 if (IsBasicUnit(singleunit)) {
277 int orderprefix = 1;
278 if (pos1 > 0) {
279 if (unitsStr[pos1 - 1] == '/') {
280 orderprefix = -1;
281 } else if (unitsStr[pos1 - 1] == '-' || unitsStr[pos1 - 1] == '*') {
282 } else {
283 RESTWarning << "illegeal unit combiner \"" << unitsStr[pos1 - 1] << "\"" << RESTendl;
284 }
285 }
286
287 double ordernum = 1;
288 if (pos2 < unitsStr.size() - 1) {
289 if (unitsStr[pos2] == '^') {
290 int pos3 = unitsStr.find_first_not_of("-0123456789.", pos2 + 1);
291 string orderstr = unitsStr.substr(pos2 + 1, pos3 - pos2 - 1);
292 ordernum = StringToDouble(orderstr);
293 pos = pos3;
294 }
295 }
296
297 int _type = GetUnitType(singleunit);
298 double _scale = GetUnitScale(singleunit);
299 double _order = ordernum * orderprefix;
300
301 fComponents.push_back(_type);
302 fComponentOrder.push_back(_order);
303
304 fScaleCombined *= pow(_scale, _order);
305 } else {
306 fZombie = true;
307 return;
308 // warning << "not a unit \"" << singleunit << "\"" << endl;
309 }
310
311 } else {
312 if (pos == unitsStr.size() - 1) {
313 RESTWarning << "last character inside \"" << unitsStr << "\" \"" << unitsStr[pos]
314 << "\" unrecognized in unit definition!" << RESTendl;
315 }
316
317 pos++;
318 }
319 }
320 if (fComponents.size() == 0) {
321 fZombie = true;
322 } else {
323 fZombie = false;
324 }
325}
326
327int TRestSystemOfUnits::GetUnitType(string singleUnit) {
328 if (IsBasicUnit(singleUnit)) {
329 return __ListOfRESTUnits[singleUnit].first;
330 }
331 return -1;
332}
333
334double TRestSystemOfUnits::GetUnitScale(string singleUnit) {
335 if (IsBasicUnit(singleUnit)) {
336 return __ListOfRESTUnits[singleUnit].second;
337 }
338 return 1;
339}
340
341string TRestSystemOfUnits::ToStandardDefinition() {
342 string result = "";
343 for (unsigned int i = 0; i < fComponents.size(); i++) {
344 if (fComponentOrder[i] < 0) {
345 result += "/";
346 } else if (i > 0) {
347 result += "-";
348 }
349
350 for (auto iter : __ListOfRESTUnits) {
351 if (iter.second.first == fComponents[i] && iter.second.second == 1) {
352 result += iter.first;
353 }
354 }
355
356 if (abs(fComponentOrder[i]) != 1) {
357 result += "^" + ToString(abs(fComponentOrder[i]));
358 }
359 }
360
361 return result;
362}
363
364} // namespace REST_Units
double GetUnitScale(std::string singleUnit)
Get the scale of the unit to convert to the REST standard units.
TRestSystemOfUnits(std::string unitsStr)
Constructor from a unit std::string.
int GetUnitType(std::string singleUnit)
Get the type of the units.
bool IsZombie() const
Whether this unit is zombie(invalid)
Double_t StringToDouble(std::string in)
Gets a double from a string.
TVector2 StringTo2DVector(std::string in)
Gets a 2D-vector from a string.
std::string Trim(std::string s, const char *t=" \t\n\r\f\v")
Removes all white spaces found at the beginning and the end of the string (https://stackoverflow....
TVector3 StringTo3DVector(std::string in)
Gets a 3D-vector from a string. Format should be : (X,Y,Z).
This namespace defines the unit conversion for different units which are understood by REST.
bool IsBasicUnit(std::string in)
Checks if the string is a REST basic unit.
Double_t GetValueInRESTUnits(std::string in)
It scales a physics measurement with its units into a REST default units value.
TVector3 Get3DVectorInRESTUnits(std::string in)
It scales a physics measurement with its units into a REST default units value.
Double_t GetDblValueInString(std::string in)
It scales a physics measurement with its units into a REST default units value.
double GetScaleToStandardUnit(std::string unitsdef)
Get the scale to REST standard unit. scale (unitsdef) = 1 (standard unit)
Double_t ConvertRESTUnitsValueToCustomUnits(Double_t value, std::string unitsStr)
Convert value with REST units into the given custom units.
std::string FindRESTUnitsInString(std::string InString)
Find and return the units definition in a string.
Double_t GetDblValueInRESTUnits(std::string in)
It scales a physics measurement with its units into a REST default units value.
std::string GetStandardUnitDefinition(std::string unitsdef)
Get standard form of this unit definition.
bool IsUnit(std::string in)
Checks if the string is a REST supported unit.
TVector2 Get2DVectorInRESTUnits(std::string in)
It scales a physics measurement with its units into a REST default units value.
Double_t ConvertValueToRESTUnits(Double_t value, std::string unitsStr)
Convert value into REST units.
TVector3 Get3DVectorValueInString(std::string in)
It scales a physics measurement with its units into a REST default units value.
TVector2 Get2DVectorValueInString(std::string in)
It scales a physics measurement with its units into a REST default units value.
std::string RemoveUnitsFromString(std::string s)
It should remove all units found inside the input string.
double _AddUnit(std::string name, int type, double scale)
Add a unit with given name, type and scale.