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

refactor: Switch to brightway #822

Open
wants to merge 32 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
ec8b69f
switch to brightway
ccomb Nov 6, 2024
b5401f9
new export
ccomb Nov 6, 2024
f9c3b6f
adapted tests
ccomb Nov 6, 2024
2623153
changed precision
ccomb Nov 6, 2024
59384f5
precision
ccomb Nov 6, 2024
e12da99
adapted tests
ccomb Nov 6, 2024
5425c6d
precision
ccomb Nov 6, 2024
24e2196
adapted tests
ccomb Nov 6, 2024
e31eeb0
adapted tests
ccomb Nov 6, 2024
f4bacfc
Merge branch 'master' of github.com:MTES-MCT/ecobalyse into switch_to…
ccomb Nov 6, 2024
8996060
new export
ccomb Nov 7, 2024
31b6e4c
Merge branch 'master' of github.com:MTES-MCT/ecobalyse into switch_to…
ccomb Nov 25, 2024
162d744
new export
ccomb Nov 26, 2024
82dc8e2
adapt tests
ccomb Nov 26, 2024
175fecb
missing simapro project for WFLDB
ccomb Nov 26, 2024
8e2e81e
reconstruct the right process name in simapro
ccomb Nov 26, 2024
cd29374
link to unit process by changing the name
ccomb Nov 26, 2024
d4349b1
patch AGB3 and not CTCPA
ccomb Nov 26, 2024
b6c0aa1
Merge branch 'master' of github.com:MTES-MCT/ecobalyse into switch_to…
ccomb Dec 5, 2024
d4c47c4
change simapro project
ccomb Dec 5, 2024
dd96e57
don't cache empty results
ccomb Dec 5, 2024
53f9cd5
use loguru
ccomb Dec 5, 2024
3827125
hack because the open project seems different than the library project
ccomb Dec 5, 2024
6ceed80
don't fail if the spapi returns a string
ccomb Dec 5, 2024
dc5056a
use the name, not the displayName
ccomb Dec 9, 2024
f0ac02a
use only normalization when displaying comparison graphs
ccomb Dec 12, 2024
6983b84
avoid needing escaping the db name
ccomb Dec 12, 2024
bf82cc2
improve biosphere to get a better ETC
ccomb Dec 12, 2024
dab2883
split comment line
ccomb Dec 12, 2024
99f10c8
Merge branch 'master' of github.com:MTES-MCT/ecobalyse into switch_to…
ccomb Dec 18, 2024
7a65646
stop on unlinked activities
ccomb Dec 18, 2024
5840241
Merge branch 'master' of github.com:MTES-MCT/ecobalyse into switch_to…
ccomb Dec 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion data/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ sync_datapackages:
@$(call DOCKER,python3 common/sync_datapackages.py)

delete_database:
@$(call DOCKER,python3 common/delete_database.py $(DB))
@$(call DOCKER,python3 common/delete_database.py "$(DB)")

delete_method:
@$(call DOCKER,python3 common/delete_methods.py)
Expand Down
18 changes: 11 additions & 7 deletions data/common/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@


def normalization_factors(impact_defs):
normalization_factors = {}
factors = {}
for k, v in impact_defs.items():
if v.get("ecoscore"):
normalization_factors[k] = (
v["ecoscore"]["weighting"] / v["ecoscore"]["normalization"]
)
if v.get("ecoscore") and "normalization" in v.get("ecoscore", {}):
factors[k] = v["ecoscore"]["normalization"]
elif v.get("pef") and "normalization" in v.get("pef", {}):
factors[k] = v["pef"]["normalization"]
else:
normalization_factors[k] = 0
return normalization_factors
pass
return factors


def spproject(activity):
Expand All @@ -28,6 +28,8 @@ def spproject(activity):
return "ADEME UPR"
case "Woolmark":
return "Woolmark"
case "WFLDB":
return "WFLDB"
case "PastoEco":
return "AGB3.1.1 2023-03-06"
case _:
Expand Down Expand Up @@ -153,6 +155,8 @@ def calculate_aggregate(process_impacts, normalization_factors):

def bytrigram(definitions, bynames):
"""takes the impact definitions and some impacts by name, return the impacts by trigram"""
if type(bynames) is not dict:
return {}
trigramsByName = {method[1]: trigram for trigram, method in definitions.items()}
return {
trigramsByName.get(name): amount["amount"]
Expand Down
16 changes: 11 additions & 5 deletions data/common/export.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ def compute_impacts(frozen_processes, default_db, impacts_py):
progress_bar(index, len(processes))
# Don't compute impacts if its a hardcoded activity
if process.get("impacts"):
logger.info(f"This process has hardcoded impacts: {process['displayName']}")
logger.info(f"This process has hardcoded impacts: {process['name']}")
continue
# simapro
activity = cached_search(
Expand All @@ -234,7 +234,7 @@ def compute_impacts(frozen_processes, default_db, impacts_py):
if not activity:
raise Exception(f"This process was not found in brightway: {process}")

results = compute_simapro_impacts(activity, main_method, impacts_py)
results = None # compute_simapro_impacts(activity, main_method, impacts_py)
# WARNING assume remote is in m3 or MJ (couldn't find unit from COM intf)
if process["unit"] == "kWh" and isinstance(results, dict):
results = {k: v * 3.6 for k, v in results.items()}
Expand Down Expand Up @@ -319,8 +319,8 @@ def plot_impacts(process_name, impacts_smp, impacts_bw, folder, impacts_py):
]
nf = normalization_factors(impacts_py)

simapro_values = [impacts_smp[label] * nf[label] for label in trigrams]
brightway_values = [impacts_bw[label] * nf[label] for label in trigrams]
simapro_values = [impacts_smp[label] / nf[label] for label in trigrams]
brightway_values = [impacts_bw[label] / nf[label] for label in trigrams]

x = numpy.arange(len(trigrams))
width = 0.35
Expand Down Expand Up @@ -394,7 +394,13 @@ def find_id(dbname, activity):


def compute_simapro_impacts(activity, method, impacts_py):
strprocess = urllib.parse.quote(activity["name"], encoding=None, errors=None)
name = (
activity["name"]
if spproject(activity) != "WFLDB"
# TODO this should probably done through disabling a strategy
else f"{activity['name']}/{activity['location']} U"
)
strprocess = urllib.parse.quote(name, encoding=None, errors=None)
project = urllib.parse.quote(spproject(activity), encoding=None, errors=None)
method = urllib.parse.quote(main_method, encoding=None, errors=None)
api_request = f"http://simapro.ecobalyse.fr:8000/impact?process={strprocess}&project={project}&method={method}"
Expand Down
5 changes: 3 additions & 2 deletions data/common/import_.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ def import_simapro_csv(

database.apply_strategies()
database.statistics()

# try to link remaining unlinked technosphere activities
database.apply_strategy(
functools.partial(
Expand All @@ -252,8 +253,8 @@ def import_simapro_csv(

print("### Adding unlinked flows and activities...")
# comment to enable stopping on unlinked activities and creating an excel file
database.add_unlinked_flows_to_biosphere_database(biosphere)
database.add_unlinked_activities()
# database.add_unlinked_flows_to_biosphere_database(biosphere)
# database.add_unlinked_activities()

# stop if there are unlinked activities
if len(list(database.unlinked)):
Expand Down
9 changes: 9 additions & 0 deletions data/common/sync_datapackages.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
# Configure logger
import sys

import bw2data
from loguru import logger

logger.remove() # Remove default handler
logger.add(sys.stderr, format="{time} {level} {message}", level="INFO")

PROJECT = "default"
print("Syncing datapackages...")
bw2data.projects.set_current(PROJECT)
for method in bw2data.methods:
logger.info(f"Syncing method {method}...")
bw2data.Method(method).process()

for database in bw2data.databases:
logger.info(f"Syncing database {database}...")
bw2data.Database(database).process()
print("done")
3 changes: 2 additions & 1 deletion data/docker/simapro-biosphere.json
Original file line number Diff line number Diff line change
Expand Up @@ -849,11 +849,12 @@
["water", "Benzene, 1,2-dichloro-", "o-Dichlorobenzene"],
["water", "Benzo(a)anthracene", "Benz(a)anthracene"],
["water", "Benzo(g,h,i)perylene", "Benzo(ghi)perylene"],
["water", "Cadmium", "Cadmium, ion"],
["water", "Cadmium", "Cadmium II"],
["water", "Calcium", "Calcium, ion"],
["water", "Carbamic acid, butyl-, 3-iodo-2-propynyl ester", "Butylcarbamate, iodopropynyl"],
["water", "Carbon", "Elemental carbon"],
["water", "Chromium", "Chromium, ion"],
["soil", "Chromium", "Chromium, ion"],
["water", "Copper", "Copper, ion"],
["soil", "Copper", "Copper, ion"],
["water", "Ethane, chloro-", "Monochloroethane"],
Expand Down
13 changes: 13 additions & 0 deletions data/import_ecoinvent.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,18 @@ def organic_cotton_irrigation(db):
STRATEGIES = [organic_cotton_irrigation]


def use_unit_processes(db):
"""the woolmark dataset comes with dependent processes
which are set as system processes.
EI3.10 has these processes but as unit processes.
So we change the name such as the linking be done"""
for ds in db:
for exc in ds["exchanges"]:
if exc["name"].endswith("Cut-off, S"):
exc["name"].replace("Cut-off, S", "Cut-off, U")
return db


def main():
projects.set_current(PROJECT)
# projects.create_project(PROJECT, activate=True, exist_ok=True)
Expand Down Expand Up @@ -79,6 +91,7 @@ def main():
import_simapro_csv(
join("..", "..", "dbfiles", WOOL),
db,
first_strategies=[use_unit_processes],
external_db="Ecoinvent 3.10", # wool is linked with EI 3.10
excluded_strategies=EXCLUDED,
)
Expand Down
9 changes: 7 additions & 2 deletions data/spapi/simapro.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,19 @@ async def impact(_: Request, project: str, process: str, method: str):
server.OpenProject(project, "")

print("Computing results...")
# hack because the open project is "WFLDB"
# but the process are in the library project "World Food LCA Database"
tmpproject = "World Food LCA Database" if project == "WFLDB" else project
existing = [
e
for e in [
((i, server.FindProcess(project, i, process)[0])) for i in range(12)
((i, server.FindProcess(tmpproject, i, process)[0])) for i in range(12)
]
if e[1]
]
found = existing[0] if len(existing) else None
if found:
server.Analyse(project, found[0], process, "Methods", method, "")
server.Analyse(tmpproject, found[0], process, "Methods", method, "")
results, i = {}, 0
try:
# try the first and stop if it raises (typically on a Dummy process.
Expand All @@ -66,6 +69,8 @@ async def impact(_: Request, project: str, process: str, method: str):
results[r.IndicatorName] = {"amount": r.Amount, "unit": r.UnitName}
i += 1
impacts.setdefault(f"{project}/{process}", {})
if not results:
return results
impacts[f"{project}/{process}"][method] = results
with open("impacts.json", "w") as fp:
json.dump(impacts, fp, ensure_ascii=False)
Expand Down
8 changes: 4 additions & 4 deletions data/textile/export.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,16 +160,16 @@ def csv_export_impact_comparison(compared_impacts):
)
csv_export_impact_comparison(impacts_compared_dic)
for process_name, values in impacts_compared_dic.items():
displayName = processes[process_name]["displayName"]
print(f"Plotting {displayName}")
name = processes[process_name]["name"]
print(f"Plotting {name}")
if "simapro_impacts" not in values and "brightway_impacts" not in values:
print(f"This hardcopied process cannot be plot: {displayName}")
print(f"This hardcopied process cannot be plot: {name}")
continue
simapro_impacts = values["simapro_impacts"]
brightway_impacts = values["brightway_impacts"]
os.makedirs(GRAPH_FOLDER, exist_ok=True)
plot_impacts(
displayName,
name,
simapro_impacts,
brightway_impacts,
GRAPH_FOLDER,
Expand Down
4 changes: 2 additions & 2 deletions public/data/object/processes.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
"swe": 0,
"tre": 0,
"wtu": 0,
"ecs": 23650.509942608354,
"pef": 27363.305839091667
"ecs": 23630.543538072445,
"pef": 27347.019127874755
}
},
{
Expand Down
Loading
Loading