Skip to content

Commit

Permalink
Keep older SimaPro import functions
Browse files Browse the repository at this point in the history
  • Loading branch information
cmutel committed Jun 21, 2024
1 parent 09d34ea commit c359634
Show file tree
Hide file tree
Showing 8 changed files with 168 additions and 53 deletions.
8 changes: 4 additions & 4 deletions bw2io/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@
"MultiOutputEcospold1Importer",
"normalize_units",
"restore_project_directory",
# "SimaProCSVImporter",
# "SimaProLCIACSVImporter",
"SimaProCSVImporter",
"SimaProLCIACSVImporter",
"SimaProBlockCSVImporter",
"SingleOutputEcospold1Importer",
"SingleOutputEcospold2Importer",
Expand Down Expand Up @@ -87,8 +87,8 @@
Exiobase3MonetaryImporter,
MultiOutputEcospold1Importer,
SimaProBlockCSVImporter,
# SimaProCSVImporter,
# SimaProLCIACSVImporter,
SimaProCSVImporter,
SimaProLCIACSVImporter,
SingleOutputEcospold1Importer,
SingleOutputEcospold2Importer,
)
Expand Down
4 changes: 2 additions & 2 deletions bw2io/importers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
from .excel_lcia import CSVLCIAImporter, ExcelLCIAImporter
from .exiobase3_hybrid import Exiobase3HybridImporter
from .exiobase3_monetary import Exiobase3MonetaryImporter
# from .simapro_csv import SimaProCSVImporter
# from .simapro_lcia_csv import SimaProLCIACSVImporter
from .simapro_csv import SimaProCSVImporter
from .simapro_lcia_csv import SimaProLCIACSVImporter
from .simapro_block_csv import SimaProBlockCSVImporter

"""
Expand Down
4 changes: 2 additions & 2 deletions bw2io/importers/simapro_block_csv.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
normalize_simapro_biosphere_names,
normalize_units,
set_code_by_activity_hash,
sp_allocate_products,
sp_allocate_functional_products,
split_simapro_name_geo,
strip_biosphere_exc_locations,
update_ecoinvent_locations,
Expand Down Expand Up @@ -55,7 +55,7 @@ def __init__(
self.project_parameters = data['project_parameters']

self.strategies = [
sp_allocate_products,
sp_allocate_functional_products,
assign_only_functional_exchange_as_reference_product,
drop_unspecified_subcategories,
split_simapro_name_geo,
Expand Down
2 changes: 2 additions & 0 deletions bw2io/strategies/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
"set_code_by_activity_hash",
"set_lognormal_loc_value",
"sp_allocate_products",
"sp_allocate_functional_products",
"special",
"split_exchanges",
"split_simapro_name_geo",
Expand Down Expand Up @@ -177,5 +178,6 @@
normalize_simapro_biosphere_names,
sp_allocate_products,
split_simapro_name_geo,
sp_allocate_functional_products,
)
from .useeio import remove_random_exchanges, remove_useeio_products
117 changes: 115 additions & 2 deletions bw2io/strategies/simapro.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from numbers import Number

import numpy as np
import bw2parameters
from bw2data import Database
from stats_arrays import LognormalUncertainty

Expand All @@ -27,7 +28,7 @@ def functional(exc: dict) -> bool:
return False


def sp_allocate_products(db):
def sp_allocate_functional_products(db):
"""
Allocate products in a SimaPro dataset by creating a separate dataset for each product.
Expand Down Expand Up @@ -135,6 +136,118 @@ def sp_allocate_products(db):
return db + new_data


def sp_allocate_products(db):
"""
Allocate products in a SimaPro dataset by creating a separate dataset for each product.
For raw SimaPro datasets, creates a separate dataset for each product,
taking into account the allocation factor if provided. Also handles
waste treatment datasets with a single product.
Parameters
----------
db : list
A list of dictionaries representing raw SimaPro datasets.
Returns
-------
new_db : list
A list of dictionaries representing the allocated datasets with separate
entries for each product.
Examples
--------
>>> db = [
... {
... "name": "Dataset 1",
... "exchanges": [
... {"type": "production", "name": "Product A", "unit": "kg", "amount": 10, "allocation": 80},
... {"type": "production", "name": "Product B", "unit": "kg", "amount": 20, "allocation": 20},
... ],
... }
... ]
>>> sp_allocate_products(db)
[
{
"name": "Product A",
"reference product": "Product A",
"unit": "kg",
"production amount": 10,
"exchanges": [
{"type": "production", "name": "Product A", "unit": "kg", "amount": 10, "allocation": 80},
{"type": "production", "name": "Product B", "unit": "kg", "amount": 5, "allocation": 20},
],
},
{
"name": "Product B",
"reference product": "Product B",
"unit": "kg",
"production amount": 5,
"exchanges": [
{"type": "production", "name": "Product A", "unit": "kg", "amount": 2.5, "allocation": 80},
{"type": "production", "name": "Product B", "unit": "kg", "amount": 5, "allocation": 20},
],
},
]
"""
new_db = []
for ds in db:
products = [
exc for exc in ds.get("exchanges", []) if exc["type"] == "production"
]
if ds.get("reference product"):
new_db.append(ds)
elif not products:
ds["error"] = True
new_db.append(ds)
elif len(products) == 1:
# Waste treatment datasets only allowed one product
product = products[0]
ds["name"] = ds["reference product"] = product["name"]
ds["unit"] = product["unit"]
ds["production amount"] = product["amount"]
new_db.append(ds)
else:
ds["exchanges"] = [
exc for exc in ds["exchanges"] if exc["type"] != "production"
]
for product in products:
product = copy.deepcopy(product)
if (allocation := product.get("allocation")):
if isinstance(product["allocation"], str) and "parameters" in ds:
ds["parameters"] = {
k.lower(): v for k, v in ds["parameters"].items()
}
interp = bw2parameters.ParameterSet(
ds["parameters"]
).get_interpreter()
interp.add_symbols(
bw2parameters.ParameterSet(
ds["parameters"]
).evaluate_and_set_amount_field()
)
allocation = interp(
normalize_simapro_formulae(
product["allocation"].lower(),
settings={"Decimal separator": ","},
)
)

if allocation != 0:
product["amount"] = product["amount"] * 1 / (allocation / 100)
else:
product["amount"] = 0 # Infinity as zero? :-/
else:
product["amount"] = 0
copied = copy.deepcopy(ds)
copied["exchanges"].append(product)
copied["name"] = copied["reference product"] = product["name"]
copied["unit"] = product["unit"]
copied["production amount"] = product["amount"]
new_db.append(copied)
return new_db


def fix_zero_allocation_products(db):
"""
Fix datasets with a single production exchange and zero allocation factors.
Expand Down Expand Up @@ -751,4 +864,4 @@ def assign_only_functional_exchange_as_reference_product(db):
ds["name"] = ds["reference product"] = product["name"]
ds["production amount"] = product["amount"]
ds["unit"] = product.get("unit") or ds.get("unit")
return db
return db
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ requires = ["setuptools>=69.0"]
build-backend = "setuptools.build_meta"

[project]
name = "bw25io"
name = "bw2io"
authors = [
{ name="Chris Mutel", email="cmutel@gmail.com" }
]
Expand Down
6 changes: 3 additions & 3 deletions tests/strategies/simapro_allocation.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from bw2io.strategies.simapro import sp_allocate_products
from bw2io.strategies.simapro import sp_allocate_functional_products


def test_sp_allocate_products():
def test_sp_allocate_functional_products():
given = [
{
"type": "multifunctional",
Expand Down Expand Up @@ -168,4 +168,4 @@ def test_sp_allocate_products():
"production amount": 2000.0,
},
]
assert sp_allocate_products(given) == expected
assert sp_allocate_functional_products(given) == expected
78 changes: 39 additions & 39 deletions tests/strategies/simapro_normalization.py
Original file line number Diff line number Diff line change
@@ -1,42 +1,42 @@
# import unittest
import unittest

# from bw2io.compatibility import SIMAPRO_BIO_SUBCATEGORIES, SIMAPRO_BIOSPHERE
# from bw2io.strategies.simapro import (
# normalize_simapro_biosphere_categories,
# normalize_simapro_biosphere_names,
# )
from bw2io.compatibility import SIMAPRO_BIO_SUBCATEGORIES, SIMAPRO_BIOSPHERE
from bw2io.strategies.simapro import (
normalize_simapro_biosphere_categories,
normalize_simapro_biosphere_names,
)


# class SPNormalizationTestCase(unittest.TestCase):
# def test_sp_biosphere_category_normalization(self):
# db = [
# {
# "exchanges": [
# {"categories": ["Economic issues", "foo"], "type": "biosphere"},
# {"categories": ["Resources", "high. pop."], "type": "biosphere"},
# {
# "categories": ["Economic issues", "high. pop."],
# "type": "not biosphere",
# },
# ],
# }
# ]
# result = [
# {
# "exchanges": [
# {"categories": ("economic", "foo"), "type": "biosphere"},
# {
# "categories": ("natural resource", "urban air close to ground"),
# "type": "biosphere",
# },
# {
# "categories": ["Economic issues", "high. pop."],
# "type": "not biosphere",
# },
# ],
# }
# ]
# self.assertEqual(
# result,
# normalize_simapro_biosphere_categories(db),
# )
class SPNormalizationTestCase(unittest.TestCase):
def test_sp_biosphere_category_normalization(self):
db = [
{
"exchanges": [
{"categories": ["Economic issues", "foo"], "type": "biosphere"},
{"categories": ["Resources", "high. pop."], "type": "biosphere"},
{
"categories": ["Economic issues", "high. pop."],
"type": "not biosphere",
},
],
}
]
result = [
{
"exchanges": [
{"categories": ("economic", "foo"), "type": "biosphere"},
{
"categories": ("natural resource", "urban air close to ground"),
"type": "biosphere",
},
{
"categories": ["Economic issues", "high. pop."],
"type": "not biosphere",
},
],
}
]
self.assertEqual(
result,
normalize_simapro_biosphere_categories(db),
)

0 comments on commit c359634

Please sign in to comment.