hgrecco / pint

Operate and manipulate physical quantities in Python
http://pint.readthedocs.org/
Other
2.41k stars 473 forks source link

Dimension Conversion Fails in Mixed Dimension Quantities #2072

Open julian-belina opened 3 weeks ago

julian-belina commented 3 weeks ago

Hi there,

Unfortunately I ran into a problem with converting mixed dimensions using contexts. I want to convert one dimension into another dimension in a mixed quantity like 1[MyDimension]/[km] -->1.43[MyOtherDimension]/[km]. If I only use my self defined dimensions 1[MyDimension]] -->1.43[MyOtherDimension], everything works as expected. However, if I mix the dimensions, the conversion fails. I have come up with the following minimal example:

import pathlib

import pint

# generate pint registry
unit_registry = pint.UnitRegistry(system="SI")
unit_registry.formatter.default_format = "~"

# add currency dimensions to pint registry
current_folder = pathlib.Path(__file__).parents[0]
path_to_registry_definition = current_folder.joinpath(r"unit_def_file.txt")
unit_registry.load_definitions(path_to_registry_definition)

# Create quantity from self defined unit in dimension 1
my_quantity = 1 * unit_registry.Unit("my_unit_1_dim_1")
# Convert to unit within the same dimension --> Works
print("Conversion 1", my_quantity.to("my_unit_2_dim_1"))

# Convert to unit in other dimension --> Works
print(
    "Conversion to other dim:", my_quantity.to("my_unit_1_dim_2", "context_dim_1_dim_2")
)
# Convert standard units using the the self defined context -->works
length_quantity = 1 * unit_registry.Unit("km")
print(length_quantity.to("m", "context_dim_1_dim_2"))

# Convert self from one self defined dimension to other self defined dimension with composite units --> Fails
my_composite_quantity = 1 * unit_registry.Unit("my_unit_1_dim_1/km")
print(my_composite_quantity.to("my_unit_1_dim_2/km", "context_dim_1_dim_2"))

Exception has occurred: DimensionalityError Cannot convert from 'my_unit_1_dim_1 / kilometer' ([my_dimension_1] / [length]) to 'my_unit_1_dim_2 / kilometer' ([my_dimension_2] / [length]

This is the context of my definition file :unit_def_file.txt

my_unit_1_dim_1=[my_dimension_1]

my_unit_2_dim_1 = my_unit_1_dim_1 2.5 

my_unit_1_dim_2=[my_dimension_2]

my_unit_2_dim_2 = my_unit_1_dim_2 4

@context context_dim_1_dim_2
    [my_dimension_1] -> [my_dimension_2] : value * 3.5 * my_unit_1_dim_2/my_unit_1_dim_1
    [my_dimension_2] -> [my_dimension_1] : (value / 3.5) * my_unit_1_dim_1/my_unit_1_dim_2
@end

I would like to use these conversions to implement inflation rates and different currencies, while also dealing with other units. A typical use case would be to convert €/l to $/gallon.

Is this a bug, have I misconfigured something or is the functionality just not implemented?Any help would be appreciated.

chrisjwin commented 3 weeks ago

second