Skip to content

Commit 09d34ea

Browse files
committed
Initial version of new SimaPro importer
1 parent 602170d commit 09d34ea

File tree

13 files changed

+749
-661
lines changed

13 files changed

+749
-661
lines changed

bw2io/__init__.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,9 @@
3838
"MultiOutputEcospold1Importer",
3939
"normalize_units",
4040
"restore_project_directory",
41-
"SimaProCSVImporter",
42-
"SimaProLCIACSVImporter",
41+
# "SimaProCSVImporter",
42+
# "SimaProLCIACSVImporter",
43+
"SimaProBlockCSVImporter",
4344
"SingleOutputEcospold1Importer",
4445
"SingleOutputEcospold2Importer",
4546
"unlinked_data",
@@ -82,13 +83,14 @@
8283
Ecospold1LCIAImporter,
8384
ExcelImporter,
8485
ExcelLCIAImporter,
86+
Exiobase3HybridImporter,
87+
Exiobase3MonetaryImporter,
8588
MultiOutputEcospold1Importer,
86-
SimaProCSVImporter,
87-
SimaProLCIACSVImporter,
89+
SimaProBlockCSVImporter,
90+
# SimaProCSVImporter,
91+
# SimaProLCIACSVImporter,
8892
SingleOutputEcospold1Importer,
8993
SingleOutputEcospold2Importer,
90-
Exiobase3MonetaryImporter,
91-
Exiobase3HybridImporter,
9294
)
9395
from .units import normalize_units
9496
from .unlinked_data import unlinked_data, UnlinkedData

bw2io/ecoinvent.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import zipfile
33
from collections import defaultdict
44
from pathlib import Path
5-
from typing import Any
5+
from typing import Any, Optional
66

77
import bw2data as bd
88
import ecoinvent_interface as ei
@@ -52,13 +52,14 @@ def pick_a_unit_label_already(obj: dict) -> str:
5252
def import_ecoinvent_release(
5353
version: str,
5454
system_model: str,
55-
username: str | None = None,
56-
password: str | None = None,
55+
username: Optional[str] = None,
56+
password: Optional[str] = None,
5757
lci: bool = True,
5858
lcia: bool = True,
59-
biosphere_name: str | None = None,
59+
biosphere_name: Optional[str] = None,
6060
biosphere_write_mode: str = "patch",
6161
importer_signal: Any = None,
62+
lcia_prefix: Optional[str] = None,
6263
) -> None:
6364
"""
6465
Import an ecoinvent LCI and/or LCIA release.
@@ -109,6 +110,9 @@ def import_ecoinvent_release(
109110
How to handle an existing biosphere database. Must be either `replace` or `patch`
110111
importer_signal
111112
Used by the Activity Browser to provide feedback during the import
113+
lcia_prefix
114+
Extra element to add before impact category definitions, e.g. "foo" ->
115+
`("foo", "global warming")`. Useful when multiple ecoinvent versions are being installed.
112116
113117
Examples
114118
--------
@@ -308,7 +312,10 @@ def import_ecoinvent_release(
308312
substituted = set()
309313

310314
for row in cfs:
311-
impact_category = (row["method"], row["category"], row["indicator"])
315+
if lcia_prefix:
316+
impact_category = (lcia_prefix, row["method"], row["category"], row["indicator"])
317+
else:
318+
impact_category = (row["method"], row["category"], row["indicator"])
312319
if row[cf_col_label] is None:
313320
continue
314321
try:

bw2io/export/excel.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -327,24 +327,24 @@ def write_headers(sheet, row):
327327
def write_row(sheet, row, data, exc=True):
328328
style = highlighted if ("input" not in data and exc) else None
329329
if exc:
330-
sheet.write_string(row, 0, data.get("name", "(unknown)"), style)
330+
sheet.write_string(row, 0, data.get("name") or "(unknown)", style)
331331
sheet.write_string(
332-
row, 1, data.get("reference product", "(unknown)"), style
332+
row, 1, data.get("reference product") or "(unknown)", style
333333
)
334334
try:
335335
sheet.write_number(row, 2, float(data.get("amount")), style)
336336
except ValueError:
337337
sheet.write_string(row, 2, "Unknown", style)
338338
else:
339-
sheet.write_string(row, 0, data.get("name", "(unknown)"), bold)
340-
sheet.write_string(row, 3, data.get("input", [""])[0], style)
341-
sheet.write_string(row, 4, data.get("unit", "(unknown)"), style)
339+
sheet.write_string(row, 0, data.get("name") or "(unknown)", bold)
340+
sheet.write_string(row, 3, (data.get("input") or [""])[0], style)
341+
sheet.write_string(row, 4, data.get("unit") or "(unknown)", style)
342342
sheet.write_string(
343-
row, 5, ":".join(data.get("categories", ["(unknown)"])), style
343+
row, 5, ":".join(data.get("categories") or ["(unknown)"]), style
344344
)
345-
sheet.write_string(row, 6, data.get("location", "(unknown)"), style)
345+
sheet.write_string(row, 6, data.get("location") or "(unknown)", style)
346346
if exc:
347-
sheet.write_string(row, 7, data.get("type", "(unknown)"), style)
347+
sheet.write_string(row, 7, data.get("type") or "(unknown)", style)
348348
sheet.write_boolean(row, 8, "input" in data, style)
349349

350350
if only_unlinked and only_activity_names:
@@ -438,10 +438,10 @@ def write_headers(sheet, row):
438438
sheet.write_string(row, index, col, bold)
439439

440440
def write_row(sheet, row, data):
441-
sheet.write_string(row, 0, data.get("name", "(unknown)"))
441+
sheet.write_string(row, 0, data.get("name") or "(unknown)")
442442
sheet.write_number(row, 1, data.get("amount", -1))
443-
sheet.write_string(row, 2, data.get("unit", "(unknown)"))
444-
sheet.write_string(row, 3, ":".join(data.get("categories", ["(unknown)"])))
443+
sheet.write_string(row, 2, data.get("unit") or "(unknown)")
444+
sheet.write_string(row, 3, ":".join(data.get("categories") or ["(unknown)"]))
445445
sheet.write_boolean(row, 4, "input" in data)
446446

447447
safe_name = safe_filename(name, False)

bw2io/importers/__init__.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@
1111
from .excel_lcia import CSVLCIAImporter, ExcelLCIAImporter
1212
from .exiobase3_hybrid import Exiobase3HybridImporter
1313
from .exiobase3_monetary import Exiobase3MonetaryImporter
14-
from .simapro_csv import SimaProCSVImporter
15-
from .simapro_lcia_csv import SimaProLCIACSVImporter
14+
# from .simapro_csv import SimaProCSVImporter
15+
# from .simapro_lcia_csv import SimaProLCIACSVImporter
16+
from .simapro_block_csv import SimaProBlockCSVImporter
1617

1718
"""
1819
This module provides classes for importing Life Cycle Impact Assessment (LCIA) data

bw2io/importers/base_lci.py

Lines changed: 29 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import warnings
55
from typing import Optional
66

7-
from bw2data import Database, config, databases, parameters
7+
from bw2data import Database, config, databases, parameters, labels
88
from bw2data.parameters import (
99
ActivityParameter,
1010
DatabaseParameter,
@@ -340,55 +340,44 @@ def match_database(
340340

341341
self.apply_strategy(functools.partial(link_iterable_by_fields, **kwargs))
342342

343-
def create_new_biosphere(self, biosphere_name, relink=True):
344-
"""Create new biosphere database from biosphere flows in ``self.data``.
343+
def create_new_biosphere(self, biosphere_name: str):
344+
"""Create new biosphere database from unlinked biosphere flows in ``self.data``"""
345+
if biosphere_name in databases:
346+
raise ValueError(f"{biosphere_name} database already exists")
345347

346-
Links all biosphere flows to new bio database if ``relink``."""
347-
assert biosphere_name not in databases, "{} database already exists".format(
348-
biosphere_name
349-
)
348+
def reformat(exc):
349+
return exc | {"type": labels.biosphere_node_default, "exchanges": [], "database": biosphere_name, "code": activity_hash(exc)}
350+
351+
bio_data = {(flow["database"], flow["code"]): flow for flow in [
352+
reformat(exc)
353+
for ds in self.data
354+
for exc in ds.get("exchanges", [])
355+
if exc["type"] in labels.biosphere_edge_types
356+
and not exc.get("input")
357+
]}
350358

351-
print("Creating new biosphere database: {}".format(biosphere_name))
359+
if not bio_data:
360+
print("Skipping biosphere database creation as all biosphere flows are linked")
361+
return
362+
363+
print(f"Creating new biosphere database {biosphere_name} with {len(bio_data)} flows")
352364

353365
with warnings.catch_warnings():
354366
warnings.simplefilter("ignore")
355367
new_bio = Database(biosphere_name)
356368
new_bio.register(
357-
format=self.format, comment="New biosphere created by LCI import"
358-
)
359-
360-
KEYS = {"name", "unit", "categories"}
361-
362-
def reformat(exc):
363-
dct = {key: value for key, value in list(exc.items()) if key in KEYS}
364-
dct.update(
365-
type="emission",
366-
exchanges=[],
367-
database=biosphere_name,
368-
code=activity_hash(dct),
369+
format=self.format, comment=f"Database for unlinked biosphere flows from {self.db_name}"
369370
)
370-
return dct
371371

372-
bio_data = [
373-
reformat(exc)
374-
for ds in self.data
375-
for exc in ds.get("exchanges", [])
376-
if exc["type"] == "biosphere"
377-
]
378-
379-
bio_data = {(ds["database"], ds["code"]): ds for ds in bio_data}
380372
new_bio.write(bio_data)
381-
382-
if relink:
383-
self.apply_strategies(
384-
[
385-
functools.partial(
386-
link_iterable_by_fields,
387-
other=list(bio_data.values()),
388-
relink=True,
389-
),
390-
]
391-
)
373+
self.apply_strategies(
374+
[
375+
functools.partial(
376+
link_iterable_by_fields,
377+
other=list(bio_data.values()),
378+
),
379+
]
380+
)
392381

393382
def add_unlinked_flows_to_biosphere_database(
394383
self, biosphere_name=None, fields={"name", "unit", "categories"}

0 commit comments

Comments
 (0)