-
-
Notifications
You must be signed in to change notification settings - Fork 252
Expand file tree
/
Copy pathunits.py
More file actions
152 lines (139 loc) · 4.76 KB
/
units.py
File metadata and controls
152 lines (139 loc) · 4.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
import numpy as np
from .mathutils.function import Function
UNITS_CONVERSION_DICT = {
# Units of length. Meter "m" is the base unit.
"mm": 1e3,
"cm": 1e2,
"dm": 1e1,
"m": 1,
"dam": 1e-1,
"hm": 1e-2,
"km": 1e-3,
"ft": 1 / 0.3048,
"in": 1 / 0.0254,
"mi": 1 / 1609.344,
"nmi": 1 / 1852,
"yd": 1 / 0.9144,
# Units of velocity. Meter per second "m/s" is the base unit.
"m/s": 1,
"km/h": 3.6,
"knot": 1.9438444924406047,
"mph": 2.2369362920544023,
"ft/s": 1 / 0.3048,
# Units of acceleration. Meter per square second "m/s^2" is the base unit.
"m/s^2": 1,
"gs": 1 / 9.80665,
"ft/s^2": 1 / 3.2808399,
# Units of pressure. Pascal "Pa" is the base unit.
"Pa": 1,
"hPa": 1e-2,
"kPa": 1e-3,
"MPa": 1e-6,
"bar": 1e-5,
"atm": 1.01325e-5,
"mmHg": 1 / 133.322,
"inHg": 1 / 3386.389,
# Units of time. Seconds "s" is the base unit.
"s": 1,
"min": 1 / 60,
"h": 1 / 3600,
"d": 1 / 86400,
# Units of mass. Kilogram "kg" is the base unit.
"mg": 1e-6,
"g": 1e-3,
"kg": 1,
"lb": 2.20462,
# Units of angle. Radian "rad" is the base unit.
"rad": 1,
"deg": 1 / 180 * np.pi,
"grad": 1 / 200 * np.pi,
}
def conversion_factor(from_unit, to_unit):
"""Returns the conversion factor from one unit to another."""
try:
incoming_factor = UNITS_CONVERSION_DICT[to_unit]
except KeyError as e:
raise ValueError(f"Unit '{to_unit}' is not supported.") from e
try:
outgoing_factor = UNITS_CONVERSION_DICT[from_unit]
except KeyError as e:
raise ValueError(f"Unit '{from_unit}' is not supported.") from e
return incoming_factor / outgoing_factor
def convert_units_Functions(variable, from_unit, to_unit, axis=1):
"""See units.convert_units() for documentation."""
# Perform conversion, take special care with temperatures
variable_source = variable.get_source()
if from_unit in ["K", "degC", "degF"]:
variable_source[:, axis] = convert_temperature(
variable_source[:, axis], from_unit, to_unit
)
else:
variable_source[:, axis] *= conversion_factor(from_unit, to_unit)
# Rename axis labels
match axis:
case 0:
variable.__inputs__[0] = variable.__inputs__[0].replace(from_unit, to_unit)
case 1:
variable.__outputs__[0] = variable.__outputs__[0].replace(
from_unit, to_unit
)
# Create new Function instance with converted data
return Function(
source=variable_source,
inputs=variable.__inputs__,
outputs=variable.__outputs__,
interpolation=variable.__interpolation__,
extrapolation=variable.__extrapolation__,
)
def convert_temperature(variable, from_unit, to_unit):
"""See units.convert_units() for documentation."""
if from_unit == to_unit:
return variable
if from_unit == "K" and to_unit == "degC":
return variable - 273.15
if from_unit == "K" and to_unit == "degF":
return (variable - 273.15) * 9 / 5 + 32
if from_unit == "degC" and to_unit == "K":
return variable + 273.15
if from_unit == "degC" and to_unit == "degF":
return variable * 9 / 5 + 32
if from_unit == "degF" and to_unit == "K":
return (variable - 32) * 5 / 9 + 273.15
if from_unit == "degF" and to_unit == "degC":
return (variable - 32) * 5 / 9
# Conversion not supported then...
raise ValueError(
f"Temperature conversion from {from_unit} to {to_unit} is not supported."
)
def convert_units(variable, from_unit, to_unit, axis=1):
"""Convert units of variable to preferred units.
Parameters
----------
variable : int, float, numpy.array, rocketpy.Function
Variable to be converted. If Function, specify axis that should
be converted.
from_unit : string
Unit of incoming data.
to_unit : string
Unit of returned data.
axis : int, optional
Axis that should be converted. 0 for x axis, 1 for y axis.
Only applies if variable is an instance of the Function class.
Default is 1, for the y axis.
Returns
-------
variable : int, float, numpy.array, rocketpy.Function
Variable converted from "from_unit" to "to_unit".
"""
if from_unit == to_unit:
# Nothing to convert, same units
return variable
if isinstance(variable, Function):
# Handle Function class
return convert_units_Functions(variable, from_unit, to_unit, axis)
else:
# Handle ints, floats, np.arrays
if from_unit in ["K", "degC", "degF"]:
return convert_temperature(variable, from_unit, to_unit)
else:
return variable * conversion_factor(from_unit, to_unit)