1
1
#!/usr/bin/env python3
2
-
2
+ # type: ignore
3
3
"""
4
- pint-convert
5
- ~~~~~~~~~~~~
4
+ pint-convert
5
+ ~~~~~~~~~~~~
6
6
7
- :copyright: 2020 by Pint Authors, see AUTHORS for more details.
8
- :license: BSD, see LICENSE for more details.
7
+ :copyright: 2020 by Pint Authors, see AUTHORS for more details.
8
+ :license: BSD, see LICENSE for more details.
9
9
"""
10
10
11
11
from __future__ import annotations
12
12
13
13
import argparse
14
14
import contextlib
15
15
import re
16
+ from typing import Any
16
17
17
18
from pint import UnitRegistry
19
+ from pint .compat import HAS_UNCERTAINTIES , ufloat
20
+
18
21
19
- parser = argparse .ArgumentParser (description = "Unit converter." , usage = argparse .SUPPRESS )
20
- parser .add_argument (
21
- "-s" ,
22
- "--system" ,
23
- metavar = "sys" ,
24
- default = "SI" ,
25
- help = "unit system to convert to (default: SI)" ,
26
- )
27
- parser .add_argument (
28
- "-p" ,
29
- "--prec" ,
30
- metavar = "n" ,
31
- type = int ,
32
- default = 12 ,
33
- help = "number of maximum significant figures (default: 12)" ,
34
- )
35
- parser .add_argument (
36
- "-u" ,
37
- "--prec-unc" ,
38
- metavar = "n" ,
39
- type = int ,
40
- default = 2 ,
41
- help = "number of maximum uncertainty digits (default: 2)" ,
42
- )
43
- parser .add_argument (
44
- "-U" ,
45
- "--with-unc" ,
46
- dest = "unc" ,
47
- action = "store_true" ,
48
- help = "consider uncertainties in constants" ,
49
- )
50
- parser .add_argument (
51
- "-C" ,
52
- "--no-corr" ,
53
- dest = "corr" ,
54
- action = "store_false" ,
55
- help = "ignore correlations between constants" ,
56
- )
57
- parser .add_argument (
58
- "fr" , metavar = "from" , type = str , help = "unit or quantity to convert from"
59
- )
60
- parser .add_argument ("to" , type = str , nargs = "?" , help = "unit to convert to" )
61
- try :
62
- args = parser .parse_args ()
63
- except SystemExit :
64
- parser .print_help ()
65
- raise
66
-
67
- ureg = UnitRegistry ()
68
- ureg .auto_reduce_dimensions = True
69
- ureg .autoconvert_offset_to_baseunit = True
70
- ureg .enable_contexts ("Gau" , "ESU" , "sp" , "energy" , "boltzmann" )
71
- ureg .default_system = args .system
72
-
73
-
74
- def _set (key : str , value ):
22
+ def _set (ureg : UnitRegistry , key : str , value : Any ):
75
23
obj = ureg ._units [key ].converter
76
24
object .__setattr__ (obj , "scale" , value )
77
25
78
26
79
- if args .unc :
80
- try :
81
- import uncertainties
82
- except ImportError :
83
- raise Exception (
84
- "Failed to import uncertainties library!\n Please install uncertainties package"
85
- )
86
-
27
+ def _define_constants (ureg : UnitRegistry ):
87
28
# Measured constants subject to correlation
88
29
# R_i: Rydberg constant
89
30
# g_e: Electron g factor
90
31
# m_u: Atomic mass constant
91
32
# m_e: Electron mass
92
33
# m_p: Proton mass
93
34
# m_n: Neutron mass
94
- # x_Cu: Copper x unit
95
- # x_Mo: Molybdenum x unit
96
- # A_s: Angstrom star
97
- R_i = (ureg ._units ["R_inf" ].converter .scale , 0.0000000000012e7 )
98
- g_e = (ureg ._units ["g_e" ].converter .scale , 0.00000000000036 )
99
- m_u = (ureg ._units ["m_u" ].converter .scale , 0.00000000052e-27 )
100
- m_e = (ureg ._units ["m_e" ].converter .scale , 0.0000000028e-31 )
101
- m_p = (ureg ._units ["m_p" ].converter .scale , 0.00000000052e-27 )
102
- m_n = (ureg ._units ["m_n" ].converter .scale , 0.00000000085e-27 )
103
- x_Cu = (ureg ._units ["x_unit_Cu" ].converter .scale , 0.00000028e-13 )
104
- x_Mo = (ureg ._units ["x_unit_Mo" ].converter .scale , 0.00000053e-13 )
105
- A_s = (ureg ._units ["angstrom_star" ].converter .scale , 0.00000090e-10 )
35
+ R_i = (ureg ._units ["R_inf" ].converter .scale , 0.0000000000021e7 )
36
+ g_e = (ureg ._units ["g_e" ].converter .scale , 0.00000000000035 )
37
+ m_u = (ureg ._units ["m_u" ].converter .scale , 0.00000000050e-27 )
38
+ m_e = (ureg ._units ["m_e" ].converter .scale , 0.00000000028e-30 )
39
+ m_p = (ureg ._units ["m_p" ].converter .scale , 0.00000000051e-27 )
40
+ m_n = (ureg ._units ["m_n" ].converter .scale , 0.00000000095e-27 )
106
41
if args .corr :
107
- # fmt: off
108
42
# Correlation matrix between measured constants (to be completed below)
109
- # R_i g_e m_u m_e m_p m_n x_Cu x_Mo A_s
43
+ # R_i g_e m_u m_e m_p m_n
110
44
corr = [
111
- [ 1.00000 , - 0.00122 , 0.00438 , 0.00225 , 0.00455 , 0.00277 , 0.00000 , 0.00000 , 0.00000 ], # R_i
112
- [- 0.00122 , 1.00000 , 0.97398 , 0.97555 , 0.97404 , 0.59702 , 0.00000 , 0.00000 , 0.00000 ], # g_e
113
- [ 0.00438 , 0.97398 , 1.00000 , 0.99839 , 0.99965 , 0.61279 , 0.00000 , 0.00000 , 0.00000 ], # m_u
114
- [ 0.00225 , 0.97555 , 0.99839 , 1.00000 , 0.99845 , 0.61199 , 0.00000 , 0.00000 , 0.00000 ], # m_e
115
- [ 0.00455 , 0.97404 , 0.99965 , 0.99845 , 1.00000 , 0.61281 , 0.00000 , 0.00000 , 0.00000 ], # m_p
116
- [ 0.00277 , 0.59702 , 0.61279 , 0.61199 , 0.61281 , 1.00000 ,- 0.00098 ,- 0.00108 ,- 0.00063 ], # m_n
117
- [ 0.00000 , 0.00000 , 0.00000 , 0.00000 , 0.00000 ,- 0.00098 , 1.00000 , 0.00067 , 0.00039 ], # x_Cu
118
- [ 0.00000 , 0.00000 , 0.00000 , 0.00000 , 0.00000 ,- 0.00108 , 0.00067 , 1.00000 , 0.00100 ], # x_Mo
119
- [ 0.00000 , 0.00000 , 0.00000 , 0.00000 , 0.00000 ,- 0.00063 , 0.00039 , 0.00100 , 1.00000 ], # A_s
120
- ]
121
- # fmt: on
45
+ [1.0 , - 0.00206 , 0.00369 , 0.00436 , 0.00194 , 0.00233 ], # R_i
46
+ [- 0.00206 , 1.0 , 0.99029 , 0.99490 , 0.97560 , 0.52445 ], # g_e
47
+ [0.00369 , 0.99029 , 1.0 , 0.99536 , 0.98516 , 0.52959 ], # m_u
48
+ [0.00436 , 0.99490 , 0.99536 , 1.0 , 0.98058 , 0.52714 ], # m_e
49
+ [0.00194 , 0.97560 , 0.98516 , 0.98058 , 1.0 , 0.51521 ], # m_p
50
+ [0.00233 , 0.52445 , 0.52959 , 0.52714 , 0.51521 , 1.0 ],
51
+ ] # m_n
122
52
try :
123
- (
124
- R_i ,
125
- g_e ,
126
- m_u ,
127
- m_e ,
128
- m_p ,
129
- m_n ,
130
- x_Cu ,
131
- x_Mo ,
132
- A_s ,
133
- ) = uncertainties .correlated_values_norm (
134
- [R_i , g_e , m_u , m_e , m_p , m_n , x_Cu , x_Mo , A_s ], corr
53
+ import uncertainties
54
+
55
+ (R_i , g_e , m_u , m_e , m_p , m_n ) = uncertainties .correlated_values_norm (
56
+ [R_i , g_e , m_u , m_e , m_p , m_n ], corr
135
57
)
136
58
except AttributeError :
137
59
raise Exception (
138
60
"Correlation cannot be calculated!\n Please install numpy package"
139
61
)
140
62
else :
141
- R_i = uncertainties .ufloat (* R_i )
142
- g_e = uncertainties .ufloat (* g_e )
143
- m_u = uncertainties .ufloat (* m_u )
144
- m_e = uncertainties .ufloat (* m_e )
145
- m_p = uncertainties .ufloat (* m_p )
146
- m_n = uncertainties .ufloat (* m_n )
147
- x_Cu = uncertainties .ufloat (* x_Cu )
148
- x_Mo = uncertainties .ufloat (* x_Mo )
149
- A_s = uncertainties .ufloat (* A_s )
150
-
151
- _set ("R_inf" , R_i )
152
- _set ("g_e" , g_e )
153
- _set ("m_u" , m_u )
154
- _set ("m_e" , m_e )
155
- _set ("m_p" , m_p )
156
- _set ("m_n" , m_n )
157
- _set ("x_unit_Cu" , x_Cu )
158
- _set ("x_unit_Mo" , x_Mo )
159
- _set ("angstrom_star" , A_s )
63
+ R_i = ufloat (* R_i )
64
+ g_e = ufloat (* g_e )
65
+ m_u = ufloat (* m_u )
66
+ m_e = ufloat (* m_e )
67
+ m_p = ufloat (* m_p )
68
+ m_n = ufloat (* m_n )
69
+
70
+ _set (ureg , "R_inf" , R_i )
71
+ _set (ureg , "g_e" , g_e )
72
+ _set (ureg , "m_u" , m_u )
73
+ _set (ureg , "m_e" , m_e )
74
+ _set (ureg , "m_p" , m_p )
75
+ _set (ureg , "m_n" , m_n )
160
76
161
77
# Measured constants with zero correlation
162
78
_set (
79
+ ureg ,
163
80
"gravitational_constant" ,
164
- uncertainties .ufloat (
165
- ureg ._units ["gravitational_constant" ].converter .scale , 0.00015e-11
166
- ),
81
+ ufloat (ureg ._units ["gravitational_constant" ].converter .scale , 0.00015e-11 ),
82
+ )
83
+
84
+ _set (
85
+ ureg ,
86
+ "d_220" ,
87
+ ufloat (ureg ._units ["d_220" ].converter .scale , 0.000000032e-10 ),
88
+ )
89
+
90
+ _set (
91
+ ureg ,
92
+ "K_alpha_Cu_d_220" ,
93
+ ufloat (ureg ._units ["K_alpha_Cu_d_220" ].converter .scale , 0.00000022 ),
94
+ )
95
+
96
+ _set (
97
+ ureg ,
98
+ "K_alpha_Mo_d_220" ,
99
+ ufloat (ureg ._units ["K_alpha_Mo_d_220" ].converter .scale , 0.00000019 ),
100
+ )
101
+
102
+ _set (
103
+ ureg ,
104
+ "K_alpha_W_d_220" ,
105
+ ufloat (ureg ._units ["K_alpha_W_d_220" ].converter .scale , 0.000000098 ),
167
106
)
168
107
169
108
ureg ._root_units_cache = {}
170
109
ureg ._build_cache ()
171
110
172
111
173
- def convert (u_from , u_to = None , unc = None , factor = None ):
112
+ if __name__ == "__main__" :
113
+ parser = argparse .ArgumentParser (
114
+ description = "Unit converter." , usage = argparse .SUPPRESS
115
+ )
116
+ parser .add_argument (
117
+ "-s" ,
118
+ "--system" ,
119
+ metavar = "sys" ,
120
+ default = "SI" ,
121
+ help = "unit system to convert to (default: SI)" ,
122
+ )
123
+ parser .add_argument (
124
+ "-p" ,
125
+ "--prec" ,
126
+ metavar = "n" ,
127
+ type = int ,
128
+ default = 12 ,
129
+ help = "number of maximum significant figures (default: 12)" ,
130
+ )
131
+ parser .add_argument (
132
+ "-u" ,
133
+ "--prec-unc" ,
134
+ metavar = "n" ,
135
+ type = int ,
136
+ default = 2 ,
137
+ help = "number of maximum uncertainty digits (default: 2)" ,
138
+ )
139
+ parser .add_argument (
140
+ "-U" ,
141
+ "--with-unc" ,
142
+ dest = "unc" ,
143
+ action = "store_true" ,
144
+ help = "consider uncertainties in constants" ,
145
+ )
146
+ parser .add_argument (
147
+ "-C" ,
148
+ "--no-corr" ,
149
+ dest = "corr" ,
150
+ action = "store_false" ,
151
+ help = "ignore correlations between constants" ,
152
+ )
153
+ parser .add_argument (
154
+ "fr" , metavar = "from" , type = str , help = "unit or quantity to convert from"
155
+ )
156
+ parser .add_argument ("to" , type = str , nargs = "?" , help = "unit to convert to" )
157
+ try :
158
+ args = parser .parse_args ()
159
+ except SystemExit :
160
+ parser .print_help ()
161
+ raise
162
+
163
+ ureg = UnitRegistry ()
164
+ ureg .auto_reduce_dimensions = True
165
+ ureg .autoconvert_offset_to_baseunit = True
166
+ ureg .enable_contexts ("Gau" , "ESU" , "sp" , "energy" , "boltzmann" )
167
+ ureg .default_system = args .system
168
+
169
+ u_from = args .fr
170
+ u_to = args .to
171
+ unc = None
172
+ factor = None
174
173
prec_unc = 0
175
174
q = ureg .Quantity (u_from )
176
175
fmt = f".{ args .prec } g"
176
+
177
177
if unc :
178
178
q = q .plus_minus (unc )
179
+
179
180
if u_to :
180
181
nq = q .to (u_to )
181
182
else :
182
183
nq = q .to_base_units ()
184
+
183
185
if factor :
184
186
q *= ureg .Quantity (factor )
185
187
nq *= ureg .Quantity (factor ).to_base_units ()
188
+
186
189
if args .unc :
187
- prec_unc = use_unc (nq .magnitude , fmt , args .prec_unc )
190
+ if not HAS_UNCERTAINTIES :
191
+ raise Exception (
192
+ "Failed to import uncertainties library!\n Please install uncertainties package"
193
+ )
194
+
195
+ _define_constants (ureg )
196
+
197
+ num = nq .magnitude
198
+ fmt = fmt
199
+ prec_unc = args .prec_unc
200
+
201
+ with contextlib .suppress (Exception ):
202
+ if isinstance (num , type (ufloat (1 , 0 ))):
203
+ full = ("{:" + fmt + "}" ).format (num )
204
+ unc = re .search (r"\+/-[0.]*([\d.]*)" , full ).group (1 )
205
+ unc = len (unc .replace ("." , "" ))
206
+ else :
207
+ unc = 0
208
+
209
+ prec_unc = max (0 , min (prec_unc , unc ))
210
+ else :
211
+ prec_unc = 0
212
+
188
213
if prec_unc > 0 :
189
214
fmt = f".{ prec_unc } uS"
190
215
else :
@@ -193,22 +218,3 @@ def convert(u_from, u_to=None, unc=None, factor=None):
193
218
194
219
fmt = "{:" + fmt + "} {:~P}"
195
220
print (("{:} = " + fmt ).format (q , nq .magnitude , nq .units ))
196
-
197
-
198
- def use_unc (num , fmt , prec_unc ):
199
- unc = 0
200
- with contextlib .suppress (Exception ):
201
- if isinstance (num , uncertainties .UFloat ):
202
- full = ("{:" + fmt + "}" ).format (num )
203
- unc = re .search (r"\+/-[0.]*([\d.]*)" , full ).group (1 )
204
- unc = len (unc .replace ("." , "" ))
205
-
206
- return max (0 , min (prec_unc , unc ))
207
-
208
-
209
- def main ():
210
- convert (args .fr , args .to )
211
-
212
-
213
- if __name__ == "__main__" :
214
- main ()
0 commit comments