Skip to content

Commit

Permalink
contribution G matrix
Browse files Browse the repository at this point in the history
  • Loading branch information
muelleram committed Jan 31, 2025
1 parent 73b9c0b commit c8198c9
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 3 deletions.
7 changes: 7 additions & 0 deletions bw_timex/dynamic_biosphere_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ def __init__(
self.cols = []
self.values = []
self.unique_rows_cols = set() # To keep track of (row, col) pairs
self.temporal_markets_col_list = [] # To keep track of temporal market columns

def build_dynamic_biosphere_matrix(
self,
Expand Down Expand Up @@ -209,6 +210,7 @@ def build_dynamic_biosphere_matrix(
)

elif idx in self.node_id_collection_dict["temporal_markets"]:
self.temporal_markets_col_list.append(process_col_index)
(
(original_db, original_code),
time,
Expand Down Expand Up @@ -236,6 +238,11 @@ def build_dynamic_biosphere_matrix(

aggregated_inventory = temporal_market_lci_dict[idx].sum(axis=1)

# multiply LCI with supply of temporal market
temporal_market_lci_dict[idx] *= self.dynamic_supply_array[
process_col_index
]

for row_idx, amount in enumerate(aggregated_inventory.A1):
bioflow = self.lca_obj.dicts.biosphere.reversed[row_idx]
((_, _), time) = self.activity_time_mapping_dict.reversed[idx]
Expand Down
86 changes: 83 additions & 3 deletions bw_timex/timex_lca.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from calendar import day_abbr
import warnings
from datetime import datetime
from functools import partial
Expand Down Expand Up @@ -36,7 +37,9 @@
extract_date_as_integer,
resolve_temporalized_node_name,
round_datetime,
convert_date_string_to_datetime,
)
import time as ti


class TimexLCA:
Expand Down Expand Up @@ -318,6 +321,7 @@ def lci(
build_datapackage: Method to create the datapackages that contain the modifications to the technosphere and biosphere matrix using the `MatrixModifier` class.
calculate_dynamic_inventory: Method to calculate the dynamic inventory if `build_dynamic_biosphere` is True.
"""
self.expand_technosphere = expand_technosphere

if not expand_technosphere and not build_dynamic_biosphere:
raise ValueError(
Expand Down Expand Up @@ -366,10 +370,86 @@ def lci(
else:
self.calculate_dynamic_inventory(from_timeline=True)

def lci_with_background_inventory(self) -> None:
if not hasattr(self, "dynamic_inventory"):
raise AttributeError(
"Dynamic lci not yet calculated. Call TimexLCA.lci(build_dynamic_biosphere=True) first."
)
self.dynamic_inventory_bg = self.dynamic_inventory.tocsc()
# 1) set all temporal market emissions to zero

for col in self.dynamic_biosphere_builder.temporal_markets_col_list:
self.dynamic_inventory_bg.data[
self.dynamic_inventory_bg.indptr[
col
] : self.dynamic_inventory_bg.indptr[col + 1]
] = 0
self.dynamic_inventory_bg.eliminate_zeros()
# 2) add all background inventory to the dynamic inventory for all temporal markets

self.dynamic_inventory_bg = self.dynamic_inventory_bg.tocoo()

dynamic_inv_row_ids = self.dynamic_inventory_bg.row.tolist()
dynamic_inv_col_ids = self.dynamic_inventory_bg.col.tolist()
dynamic_inv_data = self.dynamic_inventory_bg.data.tolist()

for id_, lci in self.temporal_market_lci_dict.items():

((_, _), time) = self.activity_time_mapping_dict.reversed[
id_
] # time of temporal market
time_in_datetime = convert_date_string_to_datetime(
self.temporal_grouping, str(time)
)
time_in_datetime = np.datetime64(time_in_datetime).astype(
"datetime64[s]"
) # now time is a numpy datetime

lci = lci.tocoo()
t0 = ti.time()

our_list = [
self.biosphere_time_mapping_dict[
(self.lca.dicts.biosphere.reversed[row_idx], time_in_datetime)
]
for row_idx in lci.row
]
t1 = ti.time()
print(f"Time for our_list: {t1-t0}")
dynamic_inv_row_ids.extend(our_list)
dynamic_inv_col_ids.extend(lci.col) # (c for c in lci.col)
dynamic_inv_data.extend(lci.data) # (d for d in lci.data)

dynamic_inventory_bg = sparse.coo_matrix( # construct the new dynamic inventory including background inventory instead of aggregated temporal market emissions
(dynamic_inv_data, (dynamic_inv_row_ids, dynamic_inv_col_ids)),
shape=self.dynamic_inventory_bg.shape,
)
self.dynamic_inventory_bg = dynamic_inventory_bg.tocsr()

def static_lcia(self) -> None:
"""
Calculates static LCIA using time-explicit LCIs with the standard static characterization
factors of the selected LCIA method using `bw2calc.lcia()`.
factors of the selected LCIA method using `bw2calc.lcia()`.def lci_with_background_inventory(self) -> None:
if not hasattr(self, "dynamic_inventory"):
raise AttributeError(
"Dynamic lci not yet calculated. Call TimexLCA.lci(build_dynamic_biosphere=True) first."
)
self.dynamic_inventory_bg = self.dynamic_inventory.copy()
# 1) set all temporal market emissions to zero
self.dynamic_inventory_bg.tocsc()
temporal_market_columns = [self.lca.activity_dict[id_] for id_ self.node_id_collection_dict["temporal_markets"]]
self.dynamic_inventory_bg[:, temporal_market_columns].data = 0
# 2) add all background inventory to the dynamic inventory for all temporal markets
self.dynamic_inventory_bg.tocsr()
for id_, lci in self.temporal_market_lci.items():
((_, _), time) = self.activity_time_mapping_dict.reversed()[id_] #time of temporal market
time_in_datetime = convert_date_string_to_datetime(
self.temporal_grouping, str(time)
) # now time is a datetime
for row_idx, row_data in enumerate(lci):
bioflow = self.lca_obj.dicts.biosphere.reversed[row_idx]
dynamic_inv_row_id= self.biosphere_time_mapping_dict[(bioflow, time_in_datetime)]
self.dynamic_inventory_bg[dynamic_inv_row_id, row_data.indices] = row_data.data # add background inventory to dynamic inventory for each time-stamped bioflow
Parameters
----------
Expand Down Expand Up @@ -599,7 +679,7 @@ def calculate_dynamic_inventory(
calculates the dynamic inventory and stores it in the attribute
`dynamic_inventory` as a matrix and in `dynamic_inventory_df` as a DataFrame.
Also calculates and stores the lci of the temporal markets in the attribute
self.temporal_market_lcis for use in contribution analysis of the background processes.
self.temporal_market_lci_dict for use in contribution analysis of the background processes.
See also
--------
Expand Down Expand Up @@ -629,7 +709,7 @@ def calculate_dynamic_inventory(
self.interdatabase_activity_mapping,
from_timeline=from_timeline,
)
self.dynamic_biomatrix, self.temporal_market_lcis = (
self.dynamic_biomatrix, self.temporal_market_lci_dict = (
self.dynamic_biosphere_builder.build_dynamic_biosphere_matrix(
from_timeline=from_timeline
)
Expand Down

0 comments on commit c8198c9

Please sign in to comment.