convert_units.h
Go to the documentation of this file.
1 /*
2  -------------------------------------------------------------------
3 
4  Copyright (C) 2008-2017, Andrew W. Steiner
5 
6  This file is part of O2scl.
7 
8  O2scl is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 3 of the License, or
11  (at your option) any later version.
12 
13  O2scl is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with O2scl. If not, see <http://www.gnu.org/licenses/>.
20 
21  -------------------------------------------------------------------
22 */
23 #ifndef O2SCL_CONVERT_UNITS_H
24 #define O2SCL_CONVERT_UNITS_H
25 
26 /** \file convert_units.h
27  \brief File defining \ref o2scl::convert_units
28 */
29 
30 #include <cstdio>
31 #include <cstdlib>
32 #include <iostream>
33 #include <map>
34 
35 #include <o2scl/misc.h>
36 #include <o2scl/constants.h>
37 #include <o2scl/string_conv.h>
38 
39 #ifndef DOXYGEN_NO_O2NS
40 namespace o2scl {
41 #endif
42 
43  /** \brief Convert units
44 
45  Allow the user to convert between two different units after
46  specifying a conversion factor. This class will also
47  automatically combine two conversion factors to create a new
48  unit conversion (but it cannot combine more than two).
49 
50  Conversions are performed by the \ref convert() function and the
51  conversion factors must be specified beforehand using the \ref
52  insert_cache() function.
53 
54  If the GNU units command is not in the local path, the user may
55  modify \ref units_cmd_string to specify the full pathname. One
56  can also modify \ref units_cmd_string to specify a different
57  <tt>units.dat</tt> file.
58 
59  \future A remove_cache() and in_cache() function to test
60  to see if a conversion is currently in the cache.
61 
62  Example:
63  \code
64  convert_units cu;
65  cu.insert_cache("in","cm",2.54);
66  cout << "12 in is " << cu.convert("in","cm",12.0) << " cm. " << endl;
67  \endcode
68 
69  An object of this type is created by \ref o2scl_settings
70  (of type \ref lib_settings_class) for several unit
71  conversions used internally in \o2 .
72 
73  \note Combining two conversions allows for some surprising
74  apparent contradictions from numerical precision errors. If
75  there are two matching unit conversion pairs which give the same
76  requested conversion factor, then one can arrange a situation
77  where the same conversion factor is reported with slightly
78  different values after adding a related conversion to the table.
79  One way to fix this is to force the class not to combine two
80  conversions by setting \ref combine_two_conv to false.
81  Alternatively, one can ensure that no combination is necessary
82  by manually adding the desired combination conversion to the
83  cache after it is first computed.
84 
85  \future Ideally, a real C++ API for the GNU units command
86  would be better.
87  */
88  class convert_units {
89 
90 #ifndef DOXYGEN_INTERNAL
91 
92  protected:
93 
94  /// The type for caching unit conversions
95  typedef struct {
96  /// The input unit
97  std::string f;
98  /// The output unit
99  std::string t;
100  /// The conversion factor
101  double c;
102  } unit_t;
103 
104  /// The cache where unit conversions are stored
105  std::map<std::string,unit_t,std::greater<std::string> > mcache;
106 
107  /// The iterator type
108  typedef std::map<std::string,unit_t,std::greater<std::string> >::iterator miter;
109 
110 #endif
111 
112  public:
113 
114  /// Verbosity (default 0)
115  int verbose;
116 
117  /** \brief If true, use a system call to units to derive new
118  conversions (default true)
119 
120  This also requires <tt>popen()</tt>.
121  */
123 
124  /// If true, throw an exception when a conversion fails (default true)
126 
127  /// If true, allow combinations of two conversions (default true)
129 
130  /// Command string to call units (default "units")
131  std::string units_cmd_string;
132 
133  convert_units();
134 
135  virtual ~convert_units() {}
136 
137  /** \brief Return the value \c val after converting using units \c
138  from and \c to
139  */
140  virtual double convert(std::string from, std::string to, double val);
141 
142  /// Manually insert a unit conversion into the cache
143  void insert_cache(std::string from, std::string to, double conv);
144 
145  /// Manually remove a unit conversion into the cache
146  void remove_cache(std::string from, std::string to);
147 
148  /// Print the present unit cache to std::cout
149  void print_cache();
150 
151  /** \brief Make a GNU \c units.dat file from the GSL constants
152 
153  If \c c_1 is true, then the second is defined in terms of
154  meters so that the speed of light is unitless. If \c hbar_1 is
155  true, then the kilogram is defined in terms of <tt>s/m^2</tt>
156  so that \f$ \hbar \f$ is unitless.
157 
158  \note Not all of the GSL constants or the canonical GNU units
159  conversions are given here.
160  */
161  void make_units_dat(std::string fname, bool c_1=false,
162  bool hbar_1=false, bool K_1=false);
163 
164  };
165 
166 #ifndef DOXYGEN_NO_O2NS
167 }
168 #endif
169 
170 #endif
std::string t
The output unit.
Definition: convert_units.h:99
bool use_gnu_units
If true, use a system call to units to derive new conversions (default true)
The main O<span style=&#39;position: relative; top: 0.3em; font-size: 0.8em&#39;>2</span>scl O$_2$scl names...
Definition: anneal.h:42
std::map< std::string, unit_t, std::greater< std::string > >::iterator miter
The iterator type.
virtual double convert(std::string from, std::string to, double val)
Return the value val after converting using units from and to.
Convert units.
Definition: convert_units.h:88
void print_cache()
Print the present unit cache to std::cout.
bool err_on_fail
If true, throw an exception when a conversion fails (default true)
std::string units_cmd_string
Command string to call units (default "units")
std::map< std::string, unit_t, std::greater< std::string > > mcache
The cache where unit conversions are stored.
int verbose
Verbosity (default 0)
bool combine_two_conv
If true, allow combinations of two conversions (default true)
void insert_cache(std::string from, std::string to, double conv)
Manually insert a unit conversion into the cache.
std::string f
The input unit.
Definition: convert_units.h:97
The type for caching unit conversions.
Definition: convert_units.h:95
void remove_cache(std::string from, std::string to)
Manually remove a unit conversion into the cache.
double c
The conversion factor.
void make_units_dat(std::string fname, bool c_1=false, bool hbar_1=false, bool K_1=false)
Make a GNU units.dat file from the GSL constants.

Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).