UnitConversionEngine.h
1/* Distributed under the Apache License, Version 2.0.
2 See accompanying NOTICE file for details.*/
3
4//----------------------------------------------------------------------------
12//----------------------------------------------------------------------------
13#pragma once
14
15#include "cdm/utils/unitconversion/QuantityTypeDescriptor.h"
16#include "cdm/utils/unitconversion/UnitDescriptor.h"
17#include "cdm/utils/unitconversion/PrefixDescriptor.h"
18#include "cdm/utils/unitconversion/QuantityConversionDescriptor.h"
19#include "cdm/utils/unitconversion/QuantityConversionKey.h"
20#include "cdm/utils/unitconversion/UnitDimension.h"
21#include <cassert>
22
24{
25private:
27public:
28 // Define vector types for holding the data structures
29 typedef std::vector<CQuantityTypeDescriptor*> QuantityTypeList;
30 typedef std::vector<CUnitDescriptor*> UnitList;
31 typedef std::vector<CPrefixDescriptor*> PrefixList;
32 typedef std::vector<CQuantityConversionDescriptor*> QuantityConversionList;
33
34 // Define hash map types for easy lookup of names and symbols
35 typedef std::unordered_map<char,unsigned int> PrefixMap;
36 typedef std::unordered_map<std::string,unsigned int> UnitSymbolMap;
37 typedef std::unordered_map<std::string,unsigned int> QuantityNameMap;
38 typedef std::unordered_map<CQuantityConversionKey, unsigned int> QuantityConversionMap;
39 typedef std::unordered_map<CUnitDimension, unsigned int> DimensionToQuantityMap;
40
42 {
43 if (uce == nullptr)
44 {
45 uce = new CUnitConversionEngine();
46 uce->LoadDefinitions();
47 }
48 return *uce;
49 }
50
51 static void DestroyEngine()
52 {
53 SAFE_DELETE(uce);
54 }
55
56 // Do conversion, using either string or CCompoundUnit specifications, and
57 // either with or without (quick) dimension checking.
58 double ConvertValue(const double &value, const CCompoundUnit &fromUnit, const CCompoundUnit &toUnit) const;
59 double ConvertValue(const double &value, const std::string &fromUnit, const std::string &toUnit) const;
60 double QuickConvertValue(const double &value, const CCompoundUnit &fromUnit, const CCompoundUnit &toUnit) const;
61 double QuickConvertValue(const double &value, const std::string &fromUnit, const std::string &toUnit) const;
62 // ConvertValueInterval basically ignores the biases in order to convert intervals of a
63 // particular unit. Useful for *adding* quantities together
64 double ConvertValueInterval(const double &value, const CCompoundUnit &fromUnit, const CCompoundUnit &toUnit) const;
65 double ConvertValueInterval(const double &value, const std::string &fromUnit, const std::string &toUnit) const;
66 double ConvertQuantityType(const double &value, const CCompoundUnit &fromUnit, const CCompoundUnit &toUnit) const;
67
68 // Simple direct lookup of a unit symbol.
69 int GetUnitID(const std::string &unitSym) const;
70
71 // Lookup a quantity type
72 int GetQuantityTypeID(const std::string &qtName) const;
73 int GetQuantityTypeID(const CUnitDimension &ud) const;
74
75 // Lookup a conversion descriptor
76 int GetQuantityConversionID(const CUnitDimension *fromDim, const CUnitDimension *toDim) const;
77
78 // Lookup quantity conversion parameters. Will automatically compute inverted parameters
79 // if looking up conversion in opposite direction from that which was defined. The two reference parameters
80 // are modified by this function to return the exponent that the original value (including
81 // its associated compound unit) must be raised to, and the conversion factor as a CCompoundUnit
82 // object that must be factored in as well. The CCompoundUnit object that serves as the
83 // conversion factor contains the mapping unit and has already been raised to the necessary power
84 // as specified by the QuantityConversionDescriptor. In the event that the requested
85 // quantity conversion is the reverse of a defined quantity conversion, the defined
86 // version's conversion parameters are transmogrified into those of the requested
87 // conversion automatically.
88 bool GetQuantityConversionParams(const CUnitDimension *fromDim, const CUnitDimension *toDim, double &fromExp, CCompoundUnit &mappingUnit) const;
89
90 // Returns a CompoundUnit corresponding to the string representation.
91 // Dynamically allocated, and caller must delete.
92 CCompoundUnit *GetCompoundUnit(const std::string &unitString) const;
93
94 // More robust symbol lookup, allows symbols with prefixes attached, and returns
95 // (via references) both the unit ID and the prefix scale factor.
96 bool LookupFullUnit(const std::string &fullUnitSym, int &unitID, double &prefixScaleFac) const
97 {
98 int prefixID;
99 bool rc = LookupFullUnit(fullUnitSym, unitID, prefixID);
100 if (rc)
101 {
102 if (prefixID != -1)
103 {
104 CPrefixDescriptor *pd = (*m_PList)[prefixID];
105 prefixScaleFac = pd->GetScaleFactor();
106 }
107 else
108 {
109 prefixScaleFac = 1.0;
110 }
111 return true;
112 }
113 else
114 {
115 return false;
116 }
117 }
118
119 bool LookupFullUnit(const std::string &fullUnitSym, int &unitID, int &prefixID) const;
120
121 // Accessor convenience methods
122 const CUnitDescriptor &GetUnitDescriptor(int unitID) const
123 {
124 assert((unitID >= 0) && (unitID < static_cast<int>(m_UList->size())));
125 return *(*m_UList)[unitID];
126 };
127
129 {
130 assert((qtID >= 0) && (qtID < static_cast<int>(m_QTList->size())));
131 return *(*m_QTList)[qtID];
132 };
133
135 {
136 assert((pfxID >= 0) && (pfxID < static_cast<int>(m_PList->size())));
137 return *(*m_PList)[pfxID];
138 };
139
141 {
142 assert((qcID >= 0) && (qcID < static_cast<int>(m_QCList->size())));
143 return *(*m_QCList)[qcID];
144 }
145
147 {
148 return m_iNumQuantities;
149 }
150
152 {
153 return m_iNumFundamentalQuantities;
154 }
155
156 void LoadDefinitions();
157
158 // These are the methods that the LoadDefinitions methods call to build up the
159 // internal database of units information
160 CUnitDescriptor *NewUnit(const std::string &name, const std::string &symbol, unsigned int quantityTypeId, const std::string &targetUnit,
161 const double &convFac, const double &bias, CUnitDescriptor::PrefixModeType mode, const std::string &prefixSet);
162 CQuantityTypeDescriptor *NewQuantityType(const std::string &name, const std::string &expansion = "", bool twentyLog = false);
163
164 CPrefixDescriptor *NewPrefix(const std::string &name, const std::string &sym, const double &scaleFac);
165 CQuantityConversionDescriptor *NewQuantityConversion(const std::string &fromTypeName, double fromExp, const std::string &toTypeName,
166 const std::string &mappingUnit);
167
168protected:
169
170
171
172private:
173 // Only want one unit conversion engine, so declare constructors private
177
178 // Make these pointers rather than the actual vectors to avoid compiler warnings
179 // about exporting STL classes
189
192
193 std::stringstream m_UCEdefs;
194 void GetUCEdefs();
195};
Definition: CompoundUnit.h:40
Definition: PrefixDescriptor.h:14
double GetScaleFactor() const
Definition: PrefixDescriptor.h:38
Definition: QuantityConversionDescriptor.h:14
Definition: QuantityTypeDescriptor.h:17
Definition: UnitConversionEngine.h:24
static CUnitConversionEngine & GetEngine(void)
Definition: UnitConversionEngine.h:41
int GetNumQuantities()
Definition: UnitConversionEngine.h:146
CUnitConversionEngine(const CUnitConversionEngine &)
Definition: UnitConversionEngine.h:175
QuantityConversionList * m_QCList
Definition: UnitConversionEngine.h:183
DimensionToQuantityMap * m_D2QMap
Definition: UnitConversionEngine.h:188
std::unordered_map< CQuantityConversionKey, unsigned int > QuantityConversionMap
Definition: UnitConversionEngine.h:38
PrefixMap * m_PMap
Definition: UnitConversionEngine.h:184
int m_iNumFundamentalQuantities
Definition: UnitConversionEngine.h:190
std::stringstream m_UCEdefs
Definition: UnitConversionEngine.h:193
const CPrefixDescriptor & GetPrefixDescriptor(int pfxID) const
Definition: UnitConversionEngine.h:134
std::vector< CPrefixDescriptor * > PrefixList
Definition: UnitConversionEngine.h:31
UnitList * m_UList
Definition: UnitConversionEngine.h:181
std::unordered_map< std::string, unsigned int > UnitSymbolMap
Definition: UnitConversionEngine.h:36
int GetNumFundamentalQuantities()
Definition: UnitConversionEngine.h:151
int m_iNumQuantities
Definition: UnitConversionEngine.h:191
QuantityTypeList * m_QTList
Definition: UnitConversionEngine.h:180
std::unordered_map< std::string, unsigned int > QuantityNameMap
Definition: UnitConversionEngine.h:37
static void DestroyEngine()
Definition: UnitConversionEngine.h:51
bool LookupFullUnit(const std::string &fullUnitSym, int &unitID, double &prefixScaleFac) const
Definition: UnitConversionEngine.h:96
QuantityConversionMap * m_QCMap
Definition: UnitConversionEngine.h:187
std::vector< CUnitDescriptor * > UnitList
Definition: UnitConversionEngine.h:30
PrefixList * m_PList
Definition: UnitConversionEngine.h:182
const CQuantityConversionDescriptor & GetQuantityConversionDescriptor(int qcID) const
Definition: UnitConversionEngine.h:140
std::unordered_map< char, unsigned int > PrefixMap
Definition: UnitConversionEngine.h:35
std::unordered_map< CUnitDimension, unsigned int > DimensionToQuantityMap
Definition: UnitConversionEngine.h:39
UnitSymbolMap * m_USMap
Definition: UnitConversionEngine.h:185
std::vector< CQuantityConversionDescriptor * > QuantityConversionList
Definition: UnitConversionEngine.h:32
void LoadDefinitions()
Definition: UnitConversionEngine.cpp:88
static CUnitConversionEngine * uce
Definition: UnitConversionEngine.h:26
std::vector< CQuantityTypeDescriptor * > QuantityTypeList
Definition: UnitConversionEngine.h:29
const CUnitDescriptor & GetUnitDescriptor(int unitID) const
Definition: UnitConversionEngine.h:122
QuantityNameMap * m_QNMap
Definition: UnitConversionEngine.h:186
const CQuantityTypeDescriptor & GetQuantityTypeDescriptor(int qtID) const
Definition: UnitConversionEngine.h:128
Definition: UnitDescriptor.h:13
PrefixModeType
Definition: UnitDescriptor.h:16
Definition: UnitDimension.h:22

Distributed under the Apache License, Version 2.0.

See accompanying NOTICE file for details.