Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow convert_gwp() with metric=None when in/out species are identical #21

Merged
merged 10 commits into from
Apr 21, 2020
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
- name: Lint with flake8
run: |
pip install flake8
find . -name "*.py" | flake8 --count --max-complexity=5 \
find . -name "*.py" | flake8 --count --max-complexity=8 \
--show-source --statistics
- name: Install and test with pytest
run: |
Expand Down
27 changes: 20 additions & 7 deletions iam_units/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,21 @@


def convert_gwp(metric, quantity, *species):
"""Convert *quantity* between emissions *species* with a GWP *metric*.
"""Convert *quantity* between GHG *species* with a GWP *metric*.

Parameters
----------
metric : 'SARGWP100' or 'AR4GWP100' or 'AR5GWP100'
Metric conversion factors to use.
metric : 'SARGWP100' or 'AR4GWP100' or 'AR5GWP100' or None
Metric conversion factors to use. May be :obj:`None` if the input and
output species are the same.
quantity : str or pint.Quantity or tuple
Quantity to convert. If a tuple, the arguments are passed to the
:class:`pint.Quantity` constructor.
species : sequence of str, length 1 or 2
Output, or input and output emissions species, e.g. ('CH4', 'CO2') to
convert mass of CH₄ to GWP-equivalent mass of CO₂. If only the output
species is provided, *quantity* must contain the name of the input
species in some location, e.g. 'tonne CH4 / year'.
Output, or (input, output) species, e.g. ('CH4', 'CO2') to convert
mass of CH₄ to GWP-equivalent mass of CO₂. If only the output species
is provided, *quantity* must contain the name of the input species in
some location, e.g. 'tonne CH4 / year'.

Returns
-------
Expand Down Expand Up @@ -63,6 +64,18 @@ def convert_gwp(metric, quantity, *species):
# Re-assemble the expression for the units or whole quantity
expr = q0 + q1

# metric may be 'None' iff the input and output species are the same
if metric is None:
if species_in == species_out:
metric = 'AR5GWP100'
elif species_in in species_out:
# Both a DimensionalityError ('CO2' → 'CO2 / a') and a ValueError
# (no metric); raise the former for pyam compat
raise pint.DimensionalityError(species_in, species_out)
else:
msg = f'Must provide GWP metric for ({species_in}, {species_out})'
raise ValueError(msg)

# Ensure a pint.Quantity object:
# - If tuple input was given, use the 2-arg constructor.
# - If not, use the 1-arg form to convert a string.
Expand Down
25 changes: 11 additions & 14 deletions iam_units/test_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,6 @@ def test_kt():
pint.UnitRegistry()('kt').to('Mt')


# 1 tonne of CH4 converted to CO2 equivalent by different metrics
EMI_DATA = [
('AR5GWP100', 28),
('AR4GWP100', 25),
('SARGWP100', 21)
]


def test_emissions_internal():
# Dummy units can be created
registry('0.5 _gwp').dimensionality == {'[_GWP]': 1.0}
Expand All @@ -79,24 +71,29 @@ def test_emissions_internal():
'Mt {} / a', # Mass rate
'kt {} / (ha * yr)', # Mass flux
])
@pytest.mark.parametrize('metric, expected_value', EMI_DATA)
@pytest.mark.parametrize('species_out', ['CO2', 'CO2e'])
def test_convert_gwp(units, metric, expected_value, species_out):
@pytest.mark.parametrize('metric, species_in, species_out, expected_value', [
('AR5GWP100', 'CH4', 'CO2', 28),
('AR5GWP100', 'CH4', 'CO2e', 28),
('AR4GWP100', 'CH4', 'CO2', 25),
('SARGWP100', 'CH4', 'CO2', 21),
(None, 'CO2', 'CO2', 1.),
])
def test_convert_gwp(units, metric, species_in, species_out, expected_value):
# Bare masses can be converted
qty = registry.Quantity(1.0, units.format(''))
expected = registry(f'{expected_value} {units}')
assert convert_gwp(metric, qty, 'CH4', species_out) == expected
assert convert_gwp(metric, qty, species_in, species_out) == expected

# '[mass] [speciesname] (/ [time])' can be converted; the input species is
# extracted from the *qty* argument
qty = f'1.0 ' + units.format('CH4')
qty = f'1.0 ' + units.format(species_in)
expected = registry(f'{expected_value} {units}')
assert convert_gwp(metric, qty, species_out) == expected

# Tuple of (vector magnitude, unit expression) can be converted where the
# the unit expression contains the input species name
arr = np.array([1.0, 2.5, 0.1])
qty = (arr, units.format('CH4'))
qty = (arr, units.format(species_in))
expected = arr * expected_value

# Conversion works
Expand Down