Skip to content

Commit

Permalink
Fix sign conversion (#346)
Browse files Browse the repository at this point in the history
Add a test for switching signs and fix the regression (from #341) that broke that conversion. Also add a test for another unit that includes a scaling factor (l/100km, used for car fuel consumption), and comment out two test cases that show the current limitations of our unit conversion function.


* Use FlexMeasures unit registry

Signed-off-by: F.N. Claessen <felix@seita.nl>

* Fix and test conversion from -W to W

Signed-off-by: F.N. Claessen <felix@seita.nl>

* Refactor

Signed-off-by: F.N. Claessen <felix@seita.nl>
  • Loading branch information
Flix6x committed Feb 1, 2022
1 parent 9ad05aa commit f99f60c
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 15 deletions.
5 changes: 5 additions & 0 deletions flexmeasures/utils/tests/test_unit_utils.py
Expand Up @@ -25,7 +25,12 @@
("m³", "m³/h", 4, None),
("MW", "kW", 1000, None),
("kWh", "kW", 4, None),
("-W", "W", -1, None),
("l/(100km)", "l/km", 0.01, None),
("°C", "K", None, [273.15, 283.15, 284.15]),
# no support for combining an offset unit with a scaling factor, but this is also overly specific
# ("-°C", "K", None, [273.15, 263.15, 262.15]),
# ("l/(10°C)", "l/(°C)", 0.1, None),
],
)
def test_convert_unit(
Expand Down
37 changes: 22 additions & 15 deletions flexmeasures/utils/unit_utils.py
Expand Up @@ -3,6 +3,7 @@

from moneyed import list_all_currencies
import importlib.resources as pkg_resources
import numpy as np
import pandas as pd
import pint

Expand Down Expand Up @@ -161,25 +162,31 @@ def convert_units(
"""Updates data values to reflect the given unit conversion."""

if from_unit != to_unit:
from_magnitudes = (
data.to_numpy() if isinstance(data, pd.Series) else np.asarray(data)
)
try:
if isinstance(data, pd.Series):
data = pd.Series(
pint.Quantity(data.values, from_unit)
.to(pint.Quantity(to_unit))
.magnitude,
index=data.index,
name=data.name,
)
from_quantities = ur.Quantity(from_magnitudes, from_unit)
except ValueError as e:
# Catch units like "-W" and "100km"
if str(e) == "Unit expression cannot have a scaling factor.":
from_quantities = ur.Quantity(from_unit) * from_magnitudes
else:
data = list(
pint.Quantity(data, from_unit).to(pint.Quantity(to_unit)).magnitude
)
raise e # reraise
try:
to_magnitudes = from_quantities.to(ur.Quantity(to_unit)).magnitude
except pint.errors.DimensionalityError:
# Catch multiplicative conversions that use the resolution, like "kWh/15min" to "kW"
multiplier = determine_unit_conversion_multiplier(
from_unit, to_unit, event_resolution
)
if isinstance(data, pd.Series):
data = multiplier * data
else:
data = [multiplier * value for value in data]
to_magnitudes = from_magnitudes * multiplier
if isinstance(data, pd.Series):
data = pd.Series(
to_magnitudes,
index=data.index,
name=data.name,
)
else:
data = list(to_magnitudes)
return data

0 comments on commit f99f60c

Please sign in to comment.