From 16dc032ef73eae58a33b7ed9a35bee000a1727dc Mon Sep 17 00:00:00 2001 From: romainsacchi Date: Mon, 5 Aug 2024 17:04:35 +0200 Subject: [PATCH] Preserve uncertainty info when regionalizing datasets. Distinguish between preserving ecoinvent and imports uncertainty. --- .../lci-battery-capacity.xlsx | Bin 33141 -> 33136 bytes premise/energy.py | 2 +- premise/export.py | 5 +- premise/inventory_imports.py | 2 +- premise/new_database.py | 21 ++--- premise/transformation.py | 72 +++++++++++++++++- premise/utils.py | 2 +- premise/validation.py | 25 +++--- 8 files changed, 92 insertions(+), 37 deletions(-) diff --git a/premise/data/additional_inventories/lci-battery-capacity.xlsx b/premise/data/additional_inventories/lci-battery-capacity.xlsx index a71e025b512235962110b6ef3187377ea2a52207..bee3e5be07388bc74b45c3fbf2761b3b4cec88ec 100644 GIT binary patch delta 9929 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 O_-nvN1Qg$YTmKI%P9`h> delta 9873 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 diff --git a/premise/energy.py b/premise/energy.py index bd52943f..976e2892 100644 --- a/premise/energy.py +++ b/premise/energy.py @@ -62,7 +62,7 @@ def import_heating_inventories( version_out=self.version, path=LCI_HEAT, system_model=self.system_model, - keep_uncertainty_data=False, + keep_uncertainty_data=True, ) datasets = inventory.merge_inventory() self.database.extend(datasets) diff --git a/premise/export.py b/premise/export.py index 3c776b66..756caa99 100644 --- a/premise/export.py +++ b/premise/export.py @@ -961,7 +961,7 @@ def check_geographical_linking(scenario, original_database): def prepare_db_for_export( - scenario, name, original_database, keep_uncertainty_data=False, biosphere_name=None + scenario, name, original_database, biosphere_name=None ): """ Prepare a database for export. @@ -979,7 +979,6 @@ def prepare_db_for_export( original_database=original_database, database=scenario["database"], db_name=name, - keep_uncertainty_data=keep_uncertainty_data, biosphere_name=biosphere_name, ) validator.run_all_checks() @@ -991,7 +990,6 @@ def _prepare_database( scenario, db_name, original_database, - keep_uncertainty_data, biosphere_name, ): @@ -999,7 +997,6 @@ def _prepare_database( scenario, name=db_name, original_database=original_database, - keep_uncertainty_data=keep_uncertainty_data, biosphere_name=biosphere_name, ) diff --git a/premise/inventory_imports.py b/premise/inventory_imports.py index 6bc2bb73..5258c81a 100644 --- a/premise/inventory_imports.py +++ b/premise/inventory_imports.py @@ -876,7 +876,7 @@ def prepare_inventory(self) -> None: # Remove uncertainty data if not self.keep_uncertainty_data: print("Remove uncertainty data.") - self.database = remove_uncertainty(self.database) + self.import_db.data = remove_uncertainty(self.import_db.data) else: check_uncertainty_data(self.import_db.data, filename=Path(self.path).stem) diff --git a/premise/new_database.py b/premise/new_database.py index 480a7090..eef23d69 100644 --- a/premise/new_database.py +++ b/premise/new_database.py @@ -514,7 +514,8 @@ def __init__( use_cached_database: bool = True, external_scenarios: list = None, quiet=False, - keep_uncertainty_data=False, + keep_imports_uncertainty=False, + keep_source_db_uncertainty=False, gains_scenario="CLE", use_absolute_efficiency=False, biosphere_name: str = "biosphere3", @@ -525,7 +526,8 @@ def __init__( self.system_model = check_system_model(system_model) self.system_model_args = system_args self.use_absolute_efficiency = use_absolute_efficiency - self.keep_uncertainty_data = keep_uncertainty_data + self.keep_imports_uncertainty = keep_imports_uncertainty + self.keep_source_db_uncertainty = keep_source_db_uncertainty self.biosphere_name = check_presence_biosphere_database(biosphere_name) # if version is anything other than 3.8 or 3.9 @@ -630,7 +632,7 @@ def __find_cached_db(self, db_name: str) -> List[dict]: db_name = f"ecospold_{self.system_model}_{self.version}" uncertainty_data = ( - "w_uncertainty" if self.keep_uncertainty_data is True else "wo_uncertainty" + "w_uncertainty" if self.keep_source_db_uncertainty is True else "wo_uncertainty" ) file_name = ( @@ -663,7 +665,7 @@ def __find_cached_inventories(self, db_name: str) -> Union[None, List[dict]]: db_name = f"ecospold_{self.system_model}_{self.version}" uncertainty_data = ( - "w_uncertainty" if self.keep_uncertainty_data is True else "wo_uncertainty" + "w_uncertainty" if self.keep_imports_uncertainty is True else "wo_uncertainty" ) file_name = ( @@ -696,7 +698,7 @@ def __clean_database(self) -> List[dict]: """ return DatabaseCleaner( self.source, self.source_type, self.source_file_path, self.version - ).prepare_datasets(self.keep_uncertainty_data) + ).prepare_datasets(self.keep_source_db_uncertainty) def __import_inventories(self) -> List[dict]: """ @@ -808,7 +810,7 @@ def __import_inventories(self) -> List[dict]: version_out=self.version, path=filepath[0], system_model=self.system_model, - keep_uncertainty_data=self.keep_uncertainty_data, + keep_uncertainty_data=self.keep_imports_uncertainty, ) datasets = inventory.merge_inventory() data.extend(datasets) @@ -1009,7 +1011,6 @@ def write_superstructure_db_to_brightway( scenario=scenario, db_name=name, original_database=self.database, - keep_uncertainty_data=self.keep_uncertainty_data, biosphere_name=self.biosphere_name, ) @@ -1033,7 +1034,6 @@ def write_superstructure_db_to_brightway( scenario=tmp_scenario, name="database", original_database=self.database, - keep_uncertainty_data=self.keep_uncertainty_data, biosphere_name=self.biosphere_name, ) @@ -1101,7 +1101,6 @@ def write_db_to_brightway(self, name: [str, List[str]] = None): scenario=scenario, db_name=name[s], original_database=self.database, - keep_uncertainty_data=self.keep_uncertainty_data, biosphere_name=self.biosphere_name, ) write_brightway_database( @@ -1176,7 +1175,6 @@ def scenario_name(scenario): scenario=scenario, db_name="database", original_database=self.database, - keep_uncertainty_data=self.keep_uncertainty_data, biosphere_name=self.biosphere_name, ) Export(scenario, filepath[s], self.version).export_db_to_matrices() @@ -1217,7 +1215,6 @@ def write_db_to_simapro(self, filepath: str = None): scenario=scenario, db_name="database", original_database=self.database, - keep_uncertainty_data=self.keep_uncertainty_data, biosphere_name=self.biosphere_name, ) export = Export(scenario, filepath, self.version) @@ -1264,7 +1261,6 @@ def write_db_to_olca(self, filepath: str = None): scenario=scenario, db_name="database", original_database=self.database, - keep_uncertainty_data=self.keep_uncertainty_data, biosphere_name=self.biosphere_name, ) Export(scenario, filepath, self.version).export_db_to_simapro( @@ -1305,7 +1301,6 @@ def write_datapackage( scenario=scenario, db_name=name, original_database=self.database, - keep_uncertainty_data=self.keep_uncertainty_data, biosphere_name=self.biosphere_name, ) diff --git a/premise/transformation.py b/premise/transformation.py index 716e42ce..42cde18a 100644 --- a/premise/transformation.py +++ b/premise/transformation.py @@ -1057,6 +1057,19 @@ def relink_datasets(self, excludes_datasets=None, alt_names=None): if len(excs_to_relink) == 0: continue + old_uncertainty = {} + + for exc in excs_to_relink: + if exc["type"] == "technosphere": + if exc.get("uncertainty type", 0) != 0: + old_uncertainty[(exc["name"], exc.get("product"), exc["unit"])] = { + "uncertainty type": exc.get("uncertainty type", 0), + "loc": exc.get("loc", 0) / exc["amount"] if exc.get("loc") else None, + "scale": exc.get("scale", 0) / exc["amount"] if exc.get("scale") else None, + "minimum": exc.get("minimum", 0) / exc["amount"] if exc.get("minimum") else None, + "maximum": exc.get("maximum", 0) / exc["amount"] if exc.get("maximum") else None, + } + # make a dictionary with the names and amounts # of the technosphere exchanges to relink # to compare with the new exchanges @@ -1085,6 +1098,17 @@ def relink_datasets(self, excludes_datasets=None, alt_names=None): act, unique_excs_to_relink, alt_names ) + # apply uncertainties, if any + if old_uncertainty: + for exc in new_exchanges: + key = (exc["name"], exc["product"], exc["unit"]) + if key in old_uncertainty: + exc["uncertainty type"] = old_uncertainty[key]["uncertainty type"] + for k, v in old_uncertainty[key].items(): + if k != "uncertainty type": + if v is not None: + exc[k] = v * exc["amount"] + # Update act["exchanges"] by removing the exchanges to relink act["exchanges"] = [e for e in act["exchanges"] if e not in excs_to_relink] # Update act["exchanges"] by adding new exchanges @@ -1574,6 +1598,12 @@ def process_cached_exchange( "location": i[2], "type": "technosphere", "amount": exchange["amount"] * i[-1], + "uncertainty type": exchange.get("uncertainty type", 0), + "loc": exchange.get("loc", 0) * i[-1], + "scale": exchange.get("scale", 0) * i[-1], + "negative": exchange.get("negative", False), + "minimum": exchange.get("minimum", 0) * i[-1], + "maximum": exchange.get("maximum", 0) * i[-1], } for i in exchanges ] @@ -1634,6 +1664,12 @@ def process_uncached_exchange( "location": dataset["location"], "type": "technosphere", "amount": exchange["amount"], + "uncertainty type": exchange.get("uncertainty type", 0), + "loc": exchange.get("loc", None), + "scale": exchange.get("scale", None), + "negative": exchange.get("negative", False), + "minimum": exchange.get("minimum", None), + "maximum": exchange.get("maximum", None), } ] @@ -1679,6 +1715,12 @@ def new_exchange(self, exchange, location, amount_multiplier): "location": location, "type": "technosphere", "amount": exchange["amount"] * amount_multiplier, + "uncertainty type": exchange.get("uncertainty type", 0), + "loc": exchange.get("loc", None), + "scale": exchange.get("scale", None), + "negative": exchange.get("negative", False), + "minimum": exchange.get("minimum", None), + "maximum": exchange.get("maximum", None), } def handle_multiple_possible_datasets( @@ -1923,6 +1965,19 @@ def relink_technosphere_exchanges( if exc["type"] == "technosphere": exchanges_before[exc["product"]] += exc["amount"] + old_uncertainty = {} + + for exc in dataset["exchanges"]: + if exc["type"] == "technosphere": + if exc.get("uncertainty type", 0) != 0: + old_uncertainty[(exc["name"], exc.get("product"), exc["unit"])] = { + "uncertainty type": exc.get("uncertainty type", 0), + "loc": exc.get("loc", 0) / exc["amount"] if exc.get("loc") else None, + "scale": exc.get("scale", 0) / exc["amount"] if exc.get("scale") else None, + "minimum": exc.get("minimum", 0) / exc["amount"] if exc.get("minimum") else None, + "maximum": exc.get("maximum", 0) / exc["amount"] if exc.get("maximum") else None, + } + new_exchanges = self.find_candidates( dataset, exclusive=exclusive, @@ -1943,14 +1998,25 @@ def relink_technosphere_exchanges( "type": "technosphere", "amount": sum(exc["amount"] for exc in exchanges), } - for (name, prod, location, unit), exchanges in groupby( + for (name, prod, location, unit, ), exchanges in groupby( sorted( - new_exchanges, key=itemgetter("name", "product", "location", "unit") + new_exchanges, key=itemgetter("name", "product", "location", "unit",) ), - key=itemgetter("name", "product", "location", "unit"), + key=itemgetter("name", "product", "location", "unit",), ) ] + # apply uncertainties, if any + if old_uncertainty: + for exc in new_exchanges: + key = (exc["name"], exc["product"], exc["unit"]) + if key in old_uncertainty: + exc["uncertainty type"] = old_uncertainty[key]["uncertainty type"] + for k, v in old_uncertainty[key].items(): + if k != "uncertainty type": + if v is not None: + exc[k] = v * exc["amount"] + dataset["exchanges"] = [ exc for exc in dataset["exchanges"] if exc["type"] != "technosphere" ] + new_exchanges diff --git a/premise/utils.py b/premise/utils.py index bd3954d9..9a67ac3e 100644 --- a/premise/utils.py +++ b/premise/utils.py @@ -308,7 +308,7 @@ def hide_messages(): """ print("Keep uncertainty data?") - print("NewDatabase(..., keep_uncertainty_data=True)") + print("NewDatabase(..., keep_source_db_uncertainty=True), keep_imports_uncertainty=True)") print("") print("Hide these messages?") print("NewDatabase(..., quiet=True)") diff --git a/premise/validation.py b/premise/validation.py index fea1c5d6..0241ff3d 100644 --- a/premise/validation.py +++ b/premise/validation.py @@ -151,7 +151,6 @@ def __init__( database, original_database=None, db_name=None, - keep_uncertainty_data=False, biosphere_name=None, ): self.original_database = original_database @@ -164,7 +163,6 @@ def __init__( self.geo = Geomap(model) self.minor_issues_log = [] self.major_issues_log = [] - self.keep_uncertainty_data = keep_uncertainty_data self.biosphere_name = biosphere_name def check_matrix_squareness(self): @@ -202,18 +200,17 @@ def check_uncertainty(self): 12: {"loc", "scale", "shape"}, } - if self.keep_uncertainty_data is True: - for ds in self.database: - for exc in ds["exchanges"]: - if int(exc.get("uncertainty type", 0)) not in [0, 1]: - if not all( - f in exc - for f in MANDATORY_UNCERTAINTY_FIELDS[ - int(exc["uncertainty type"]) - ] - ): - message = f"Exchange {exc['name']} has incomplete uncertainty data." - self.log_issue(ds, "incomplete uncertainty data", message) + for ds in self.database: + for exc in ds["exchanges"]: + if int(exc.get("uncertainty type", 0)) not in [0, 1]: + if not all( + f in exc + for f in MANDATORY_UNCERTAINTY_FIELDS[ + int(exc["uncertainty type"]) + ] + ): + message = f"Exchange {exc['name']} has incomplete uncertainty data." + self.log_issue(ds, "incomplete uncertainty data", message) def check_datasets_integrity(self): # Verify no unintended loss of datasets