def _sum_variables_and_add_scores(self, market, variables): """ Sum the variables that belong to the market and calculate the LCA scores for all years, regions and methods. """ df = self.data[self.data.Variable.isin(variables)]\ .groupby(["Region", "Year"])\ .sum() df.reset_index(inplace=True) df["Market"] = market # add methods dimension & score column methods_df = pd.DataFrame({"Method": self.methods, "Market": market}) df = df.merge(methods_df) df.loc[:, "score"] = 0. df.loc[:, "score_direct"] = 0. df.set_index(["Year", "Region", "Method"], inplace=True) # calc score for year in self.years: db = bw.Database(eidb_label(self.model, self.scenario, year)) # database indexes of powerplants pps = [ pp for pp in db if pp["unit"] == "kilowatt hour" and "market" not in pp["name"] ] lca = bw.LCA({pps[0]: 1}) lca.lci() pp_idxs = [lca.activity_dict[pp.key] for pp in pps] for region in self.regions: # find activity act = [ a for a in db if a["name"] == market and a["location"] == region ][0] # create first lca object lca = bw.LCA({act: 1}, method=self.methods[0]) # build inventories lca.lci() for method in self.methods: lca.switch_method(method) lca.lcia() df.at[(year, region, method), "score"] = lca.score res_vec = np.squeeze( np.asarray(lca.characterized_inventory.sum(axis=0))) df.at[(year, region, method), "score_direct"] = np.sum(res_vec[pp_idxs]) df["total_score"] = df["score"] * df["value"] * 2.8e11 # EJ -> kWh df["total_score_direct"] = df["score_direct"] * df[ "value"] * 2.8e11 # EJ -> kWh return df
def _get_material_bioflows_for_bev(self): """ Obtain bioflow ids for *interesting* materials. These are the top bioflows in the ILCD materials characterization method for an BEV activity. """ method = ('ILCD 2.0 2018 midpoint', 'resources', 'minerals and metals') year = self.years[0] act_str = "transport, passenger car, fleet average, battery electric, {}".format(year) # upstream material demands are the same for all regions # so we can use GLO here act = Activity( Act.get((Act.name == act_str) & (Act.database == eidb_label( self.model, self.scenario, year)) & (Act.location == "EUR"))) lca = bw.LCA({act: 1}, method=method) lca.lci() lca.lcia() inv_bio = {value: key for key, value in lca.biosphere_dict.items()} ca = ContributionAnalysis() ef_contrib = ca.top_emissions(lca.characterized_inventory) return [inv_bio[int(el[1])] for el in ef_contrib]
def report_tech_LCA(self, year): """ For each REMIND technology, find a set of activities in the region. Use ecoinvent tech share file to determine the shares of technologies within the REMIND proxies. """ tecf = pd.read_csv(DATA_DIR/"powertechs.csv", index_col="tech") tecdict = tecf.to_dict()["mif_entry"] db = bw.Database("_".join(["ecoinvent", self.scenario, str(year)])) result = self._cartesian_product({ "region": self.regions, "tech": list(tecdict.keys()), "method": self.methods }).sort_index() for region in self.regions: # read the ecoinvent techs for the entries shares = self.supplier_shares(db, region) for tech, acts in shares.items(): # calc LCA lca = bw.LCA(acts, self.methods[0]) lca.lci() for method in self.methods: lca.switch_method(method) lca.lcia() result.at[(region, tech, method), "score"] = lca.score return result
def setup_lca_model_oases(path_base, num_params=None, write_dir_name=None, flag_generate_scores_dict=False): # LCA model bw.projects.set_current("GSA for oases") co = bw.Database("CH consumption 1.0") demand_act = [ act for act in co if "ch hh average consumption" in act["name"] ] assert len(demand_act) == 1 demand_act = demand_act[0] demand = {demand_act: 1} method = ("IPCC 2013", "climate change", "GWP 100a") # num_params if num_params is None: lca = bw.LCA(demand, method) lca.lci() lca.lcia() print("LCA score is {}".format(lca.score)) all_uncertain_params = lca.tech_params[ lca.tech_params["uncertainty_type"] > 1] num_params = len(all_uncertain_params) print("Total number of uncertain exchanges is {}".format(num_params)) # Define some variables if write_dir_name is None: write_dir_name = "oases_gsa_gwp_{}".format(num_params) write_dir = path_base / write_dir_name if flag_generate_scores_dict: model = LCAModel(demand, method, write_dir) # generate scores_dict del model model = LCAModel(demand, method, write_dir, num_params=num_params) gsa_seed = 92374523 return model, write_dir, gsa_seed
def __init__(self, cs_name): if cs_name not in bw.calculation_setups: raise ValueError( "{} is not a known `calculation_setup`.".format(cs_name)) self.cs_name = cs_name cs = bw.calculation_setups[cs_name] self.seed = None self.cf_rngs = {} self.CF_rng_vectors = {} self.include_technosphere = True self.include_biosphere = True self.include_cfs = True self.include_parameters = True self.param_rng = None self.param_cols = ["input", "output", "type"] self.tech_rng: Optional[Union[MCRandomNumberGenerator, np.ndarray]] = None self.bio_rng: Optional[Union[MCRandomNumberGenerator, np.ndarray]] = None self.cf_rng: Optional[Union[MCRandomNumberGenerator, np.ndarray]] = None # functional units self.func_units = cs['inv'] self.rev_fu_index = {i: fu for i, fu in enumerate(self.func_units)} # activities self.activity_keys = [list(fu.keys())[0] for fu in self.func_units] self.activity_index = { key: index for index, key in enumerate(self.activity_keys) } self.rev_activity_index = {v: k for k, v in self.activity_keys} # self.fu_index = {k: i for i, k in enumerate(self.activity_keys)} # methods self.methods = cs['ia'] self.method_index = {m: i for i, m in enumerate(self.methods)} self.rev_method_index = {v: k for k, v in self.method_index.items()} # todo: get rid of the below self.func_unit_translation_dict = { str(bw.get_activity(list(func_unit.keys())[0])): func_unit for func_unit in self.func_units } self.func_key_dict = { m: i for i, m in enumerate(self.func_unit_translation_dict.keys()) } self.func_key_list = list(self.func_key_dict.keys()) self.results = [] self.lca = bw.LCA(demand=self.func_units_dict, method=self.methods[0])
def get_lca(fu, method): """Calculates a non-stochastic LCA and returns a the LCA object.""" lca = bw.LCA(fu, method=method) lca.lci() lca.lcia() print('Non-stochastic LCA score:', lca.score) # add reverse dictionaries lca.activity_dict_rev, lca.product_dict_rev, lca.biosphere_dict_rev = lca.reverse_dict() return lca
def static_calc(flow, amount, methods, factorize=False): """Establish static calculation basis. By default no factorization.""" # if not isinstance(flow, Mapping): # raise ValueError("Flow must be a dictionary") for key in flow: if not key: raise ValueError("Invalid dictionary") lca = bw2.LCA({flow: amount}, method=methods) lca.lci() if factorize: lca.decompose_technosphere() lca.lcia() return lca.score
def doLCA(oActivity, aoMethods, HHV=None): if HHV: functional_unit = {oActivity: 1 / HHV} else: functional_unit = {oActivity: 1} oLCA = bw.LCA(functional_unit, aoMethods[0]) oLCA.lci() oLCA.lcia() dScores = {aoMethods[0]: oLCA.score} for oMethod in aoMethods[1:]: oLCA.switch_method(oMethod) oLCA.lcia() dScores[oMethod] = oLCA.score return dScores, oLCA
def report_endpoint(self): """ *DEPRECATED* Report the surplus extraction costs for the scenario. :return: A `pandas.Series` containing extraction costs with index `year` and `region`. """ indicatorgroup = 'ReCiPe Endpoint (H,A) (obsolete)' endpoint_methods = [ m for m in bw.methods if m[0] == indicatorgroup and m[2] == "total" and not m[1] == "total" ] df = self.data[self.data.Variable.isin(self.variables)] df.set_index(["Year", "Region", "Variable"], inplace=True) start = time.time() result = {} # calc score for year in self.years: db = bw.Database(eidb_label(self.model, self.scenario, year)) for region in self.regions: # create large lca demand object demand = [ self._act_from_variable(var, db, year, region, scale=df.loc[(year, region, var), "value"]) for var in (df.loc[( year, region)].index.get_level_values(0).unique()) ] # flatten dictionaries demand = {k: v for item in demand for k, v in item.items()} lca = bw.LCA(demand, method=endpoint_methods[0]) # build inventories lca.lci() for method in endpoint_methods: lca.switch_method(method) lca.lcia() # 6% discount for monetary endpoint factor = 1e9 * 1.06 ** (year - 2013) \ if "resources" == method[1] else 1e9 result[(year, region, method)] = lca.score * factor df_result = pd.Series(result) print("Calculation took {} seconds.".format(time.time() - start)) return df_result # billion pkm
def report_LDV_LCA(self): """ Report per-drivetrain impacts along the given dimension. Both per-pkm as well as total numbers are given. :return: a dataframe with impacts for the REMIND EDGE-T transport sector model. Levelized impacts (per pkm) are found in the column `score_pkm`, total impacts in `total_score`. :rtype: pandas.DataFrame """ df = self.data[self.data.Variable.isin(self.variables)] df.loc[:, "score_pkm"] = 0. # add methods dimension & score column methods_df = pd.DataFrame({"Method": self.methods, "score_pkm": 0.}) df = df.merge(methods_df, "outer") # on "score_pkm" df.set_index(["Year", "Region", "Variable", "Method"], inplace=True) start = time.time() # calc score for year in self.years: # find activities which at the moment do not depend # on regions db = bw.Database(eidb_label(self.model, self.scenario, year)) for region in self.regions: for var in (df.loc[(year, region)] .index.get_level_values(0) .unique()): demand = self._act_from_variable(var, db, year, region) lca = bw.LCA(demand, method=self.methods[0]) # build inventories lca.lci() if "_LowD" in self.scenario: fct = max(1 - (year - 2020)/15 * 0.15, 0.85) else: fct = 1. for method in self.methods: lca.switch_method(method) lca.lcia() df.loc[(year, region, var, method), "score_pkm"] = lca.score * fct print("Calculation took {} seconds.".format(time.time() - start)) df["total_score"] = df["value"] * df["score_pkm"] * 1e9 return df[["total_score", "score_pkm"]]
def report_materials(self): """ Report the material demand of the LDV fleet for all regions and years. :return: A `pandas.Series` with index `year`, `region` and `material`. """ # materials bioflows = self._get_material_bioflows_for_bev() df = self.data[self.data.Variable.isin(self.variables)] df.set_index(["Year", "Region", "Variable"], inplace=True) start = time.time() result = {} # calc score for year in self.years: db = bw.Database(eidb_label(self.model, self.scenario, year)) for region in self.regions: # create large lca demand object demand = [ self._act_from_variable( var, db, year, region, scale=df.loc[(year, region, var), "value"]) for var in (df.loc[(year, region)] .index.get_level_values(0) .unique())] # flatten dictionaries demand_flat = {} for item in demand: for act, val in item.items(): demand_flat[act] = val + demand_flat.get(act, 0) lca = bw.LCA(demand_flat) # build inventories lca.lci() for code in bioflows: result[( year, region, bw.get_activity(code)["name"].split(",")[0] )] = ( lca.inventory.sum(axis=1)[ lca.biosphere_dict[code], 0] ) df_result = pd.Series(result) print("Calculation took {} seconds.".format(time.time() - start)) return df_result * 1e9 # kg
def report_midpoint_to_endpoint(self): """ *DEPRECATED* Report midpoint impacts for the full fleet for each scenario. :return: A `pandas.Series` containing impacts with index `year`,`region` and `method`. """ methods = [ m for m in bw.methods if m[0] == "ReCiPe Endpoint (H,A) (obsolete)" and m[2] != "total" ] df = self.data[self.data.Variable.isin(self.variables)] df.set_index(["Year", "Region", "Variable"], inplace=True) start = time.time() result = {} # calc score for year in self.years: db = bw.Database(eidb_label(self.model, self.scenario, year)) for region in self.regions: # create large lca demand object demand = [ self._act_from_variable(var, db, year, region, scale=df.loc[(year, region, var), "value"]) for var in (df.loc[( year, region)].index.get_level_values(0).unique()) ] # flatten dictionaries demand = {k: v for item in demand for k, v in item.items()} lca = bw.LCA(demand, method=self.methods[0]) # build inventories lca.lci() for method in methods: lca.switch_method(method) lca.lcia() factor = 1e9 result[(year, region, method)] = lca.score * factor df_result = pd.Series(result) print("Calculation took {} seconds.".format(time.time() - start)) return df_result # billion pkm
def LCA_to_df(datasets, cats=['CC', 'R_Total'], amount=1, names=['name', 'location']): """Calcuate a LCA for a list of datasets for a list of methods and return a pandas dataframe. """ results = {} index_dict = {} # create lca object if datasets and cats: lca = bw.LCA({datasets[0]: 1}, method=lcia_methods[cats[0]]) lca.lci() lca.lcia() else: raise ValueError( "No datasets or impact categories found." + "Provide at least one dataset and one impact category.") for ds in datasets: index_dict[ds['code']] = tuple(ds[i] for i in names) for cat in cats: print(cat) lca.switch_method(lcia_methods[cat]) results[cat] = {} for dataset in pyprind.prog_bar(datasets): lca.redo_lcia({dataset: amount}) results[cat][dataset['code']] = lca.score # We group all energy into one category: for cat in category_group: if cat in results.keys(): for key in results[cat].keys(): if 'CED' not in results.keys(): results['CED'] = {} try: results['CED'][key] += results[cat][key] except KeyError: results['CED'][key] = results[cat][key] del results[cat] return pd.DataFrame(results).rename(index=index_dict)
def _sum_variables_and_add_scores(self, market, variables): """ Sum the variables that belong to the market and calculate the LCA scores for all years, regions and methods. """ df = self.data[self.data.Variable.isin(variables)]\ .groupby(["Region", "Year"])\ .sum() df.reset_index(inplace=True) df["market"] = market # add methods dimension & score column methods_df = pd.DataFrame({"method": self.methods, "market": market}) df = df.merge(methods_df) df.loc[:, "score"] = 0. # calc score for year in self.years: db = bw.Database(eidb_label(self.model, self.scenario, year)) for region in self.regions: # import ipdb;ipdb.set_trace() # find activity act = [a for a in db if a["name"] == market and a["location"] == region][0] # create first lca object lca = bw.LCA({act: 1}, method=df.method[0]) # build inventories lca.lci() df_slice = df[(df.Year == year) & (df.Region == region)] def get_score(method): lca.switch_method(method) lca.lcia() return lca.score df_slice.loc[:, "score"] = df_slice.apply( lambda row: get_score(row["method"]), axis=1) df.update(df_slice) df["total_score"] = df["score"] * df["value"] * 2.8e11 # EJ -> kWh return df
def __init__(self, func_unit, method, write_dir): self.lca = bw.LCA(func_unit, method) self.lca.lci() self.lca.lcia() self.write_dir = write_dir self.make_dirs() # self.uncertain_tech_params_where = np.where(self.lca.tech_params['uncertainty_type'] > 1)[0] # self.uncertain_tech_params = self.lca.tech_params[self.uncertain_tech_params_where] self.uncertain_tech_params_where = self.get_LSA_params( var_threshold=0) # TODO change the threshold self.uncertain_tech_params = self.lca.tech_params[ self.uncertain_tech_params_where] self.num_params = self.__num_input_params__() self.influential_params = [] self.choices = uncertainty_choices self.mc = MCRandomNumberGenerator(self.uncertain_tech_params)
def setup_lca_model_paper(path_base, num_params=None, write_dir=None, flag_generate_scores_dict=False): # LCA model bw.projects.set_current("GSA for paper") co = bw.Database("CH consumption 1.0") demand_act = [act for act in co if "Food" in act["name"]] assert len(demand_act) == 1 demand_act = demand_act[0] demand = {demand_act: 1} method = ("IPCC 2013", "climate change", "GWP 100a") # num_params if num_params is None: lca = bw.LCA(demand, method) lca.lci() lca.lcia() print("LCA score is {}".format(lca.score)) all_uncertain_params = lca.tech_params[ lca.tech_params["uncertainty_type"] > 1] num_params = len(all_uncertain_params) print("Total number of uncertain exchanges is {}".format(num_params)) # Define some variables if write_dir is None: # path_base = Path('/data/user/kim_a/paper_gsa') write_dir = path_base / "lca_model_food_{}".format(num_params) if flag_generate_scores_dict: model = LCAModel(demand, method, write_dir) # generate scores_dict del model model = LCAModel( demand, method, write_dir, num_params=num_params, uncertain_exchanges_types=["tech"], ) # gsa_seed = 92374523 gsa_seed = 6000814 return model, write_dir, gsa_seed
def __init__(self, cs_name): try: cs = bw.calculation_setups[cs_name] except KeyError: raise ValueError( "{} is not a known `calculation_setup`.".format(cs_name)) self.func_units = cs['inv'] self.methods = cs['ia'] self.lca = bw.LCA(demand=self.all, method=self.methods[0]) self.lca.lci(factorize=True) self.method_matrices = [] self.results = np.zeros((len(self.func_units), len(self.methods))) # contribution matrices self.process_contributions = np.zeros( (len(self.func_units), len(self.methods), self.lca.technosphere_matrix.shape[0])) self.elementary_flow_contributions = np.zeros( (len(self.func_units), len(self.methods), self.lca.biosphere_matrix.shape[0])) (self.rev_activity_dict, self.rev_product_dict, self.rev_biosphere_dict) = self.lca.reverse_dict() for method in self.methods: self.lca.switch_method(method) self.method_matrices.append(self.lca.characterization_matrix) for row, func_unit in enumerate(self.func_units): self.lca.redo_lci(func_unit) for col, cf_matrix in enumerate(self.method_matrices): self.lca.characterization_matrix = cf_matrix self.lca.lcia_calculation() self.results[row, col] = self.lca.score self.process_contributions[ row, col] = self.lca.characterized_inventory.sum(axis=0) self.elementary_flow_contributions[row, col] = np.array( self.lca.characterized_inventory.sum(axis=1)).ravel()
def report_tech_LCA(self, year): """ For each REMIND technology, find a set of activities in the region. Use ecoinvent tech share file to determine the shares of technologies within the REMIND proxies. """ tecf = pd.read_csv(DATA_DIR / "powertechs.csv", index_col="tech") tecdict = tecf.to_dict()["mif_entry"] db = bw.Database(eidb_label(self.model, self.scenario, year)) result = self._cartesian_product({ "region": self.regions, "tech": list(tecdict.keys()), "method": self.methods }).sort_index() for region in self.regions: # read the ecoinvent techs for the entries shares = self.supplier_shares(db, region) for tech, acts in shares.items(): # calc LCA lca = bw.LCA(acts, self.methods[0]) lca.lci() for method in self.methods: lca.switch_method(method) lca.lcia() result.at[(region, tech, method), "score"] = lca.score res_vec = np.squeeze( np.asarray(lca.characterized_inventory.sum(axis=0))) result.at[(region, tech, method), "score_direct"] = np.sum(res_vec[pp_idxs]) return result
def __init__(self, up_db_name, agg_db_name, database_type='LCIA', method_list=[], biosphere='biosphere3', overwrite=False): assert up_db_name in bw.databases, "Source database does not exist" if agg_db_name in bw.databases and not overwrite: warnings.warn( "A database named {} already exists, set `overwrite` to True to overwrite" .format(agg_db_name)) return self.source = bw.Database(up_db_name) self.new_name = agg_db_name self.biosphere = biosphere self.lca = bw.LCA({self.source.random(): 1}) self.lca.lci(factorize=True) self.database_type = database_type self.methods = method_list if self.database_type not in ['LCI', 'LCIA']: raise ValueError( '{} is not a valid database type, should be "LCI" or "LCIA"'. format(self.database_type)) if self.database_type == "LCIA": if not self.methods: raise ValueError( "Need to pass a list of method identifiers to create an LCIA score database, none passed" ) for m in self.methods: if any([(self.biosphere, bw.Method(m).get_abbreviation()) not in [cf[0] for cf in bw.Method(m).load()], (self.biosphere, bw.Method(m).get_abbreviation()) not in bw.Database(self.biosphere)]): add_unit_score_exchange_and_cf(m, biosphere) self.C_matrices = {}
def __init__(self, parent=None): super().__init__(parent) self.label = QtWidgets.QLabel('hello') self.grid_lay = QtWidgets.QGridLayout() self.grid_lay.addWidget(QtWidgets.QLabel('Activity: '), 0, 0) self.grid_lay.addWidget(QtWidgets.QLabel('Method: '), 1, 0) self.cs = self.window().left_panel.cs_tab.list_widget.name self.func_units = bw.calculation_setups[self.cs]['inv'] self.func_units = [{bw.get_activity(k): v for k, v in fu.items()} for fu in self.func_units] self.methods = bw.calculation_setups[self.cs]['ia'] self.func_unit_cb = QtWidgets.QComboBox() self.func_unit_cb.addItems( [list(fu.keys())[0].__repr__() for fu in self.func_units]) self.method_cb = QtWidgets.QComboBox() self.method_cb.addItems([m.__repr__() for m in self.methods]) self.grid_lay.addWidget(self.func_unit_cb, 0, 1) self.grid_lay.addWidget(self.method_cb, 1, 1) self.reload_pb = QtWidgets.QPushButton('Reload') self.reload_pb.clicked.connect(self.new_sankey) self.grid_lay.addWidget(self.reload_pb, 2, 0) self.close_pb = QtWidgets.QPushButton('Close') self.close_pb.clicked.connect(self.switch_to_main) self.grid_lay.setColumnStretch(4, 1) self.grid_lay.addWidget(self.close_pb, 0, 5) self.color_attr_cb = QtWidgets.QComboBox() self.color_attr_cb.addItems(['flow', 'location', 'name']) self.grid_lay.addWidget(QtWidgets.QLabel('color by: '), 0, 2) self.grid_lay.addWidget(self.color_attr_cb, 0, 3) self.grid_lay.addWidget(QtWidgets.QLabel('cutoff: '), 1, 2) self.cutoff_sb = QtWidgets.QDoubleSpinBox() self.cutoff_sb.setRange(0.0, 1.0) self.cutoff_sb.setSingleStep(0.001) self.cutoff_sb.setDecimals(4) self.cutoff_sb.setValue(0.005) self.cutoff_sb.setKeyboardTracking(False) self.grid_lay.addWidget(self.cutoff_sb, 1, 3) self.hlay = QtWidgets.QHBoxLayout() self.hlay.addLayout(self.grid_lay) # qt js interaction self.bridge = Bridge() self.bridge.viewer_waiting.connect(self.send_json) self.bridge.link_clicked.connect(self.expand_sankey) self.channel = QtWebChannel.QWebChannel() self.channel.registerObject('bridge', self.bridge) self.view = QtWebEngineWidgets.QWebEngineView() self.view.page().setWebChannel(self.channel) html = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'activity-browser-sankey.html') self.url = QtCore.QUrl.fromLocalFile(html) wait_html = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'spinner.html') self.wait_url = QtCore.QUrl.fromLocalFile(wait_html) self.view.load(self.wait_url) self.vlay = QtWidgets.QVBoxLayout() self.vlay.addLayout(self.hlay) self.vlay.addWidget(self.view) self.setLayout(self.vlay) # sankey demand_all = dict(collections.ChainMap(*self.func_units)) self.lca = bw.LCA(demand_all, bw.methods.random()) self.lca.lci() self.lca.lcia() self.new_sankey() self.func_unit_cb.currentIndexChanged.connect(self.new_sankey) self.method_cb.currentIndexChanged.connect(self.new_sankey) self.color_attr_cb.currentIndexChanged.connect(self.update_colors) self.cutoff_sb.valueChanged.connect(self.new_sankey) # connections sankeysignals.calculating_gt.connect(self.busy_indicator) sankeysignals.initial_sankey_ready.connect(self.draw_sankey)
def __init__(self, cs_name): if cs_name not in bw.calculation_setups: raise ValueError( "{} is not a known `calculation_setup`.".format(cs_name)) self.cs_name = cs_name self.cs = bw.calculation_setups[cs_name] self.seed = None self.cf_rngs = {} self.CF_rng_vectors = {} self.include_technosphere = True self.include_biosphere = True self.include_cfs = True self.include_parameters = True self.param_rng = None self.param_cols = ["row", "col", "type"] self.tech_rng: Optional[Union[MCRandomNumberGenerator, np.ndarray]] = None self.bio_rng: Optional[Union[MCRandomNumberGenerator, np.ndarray]] = None self.cf_rng: Optional[Union[MCRandomNumberGenerator, np.ndarray]] = None # functional units self.func_units = self.cs['inv'] self.rev_fu_index = {i: fu for i, fu in enumerate(self.func_units)} # activities self.activity_keys = [list(fu.keys())[0] for fu in self.func_units] self.activity_index = { key: index for index, key in enumerate(self.activity_keys) } self.rev_activity_index = { index: key for index, key in enumerate(self.activity_keys) } # previously: self.rev_activity_index = {v: k for k, v in self.activity_keys} # self.fu_index = {k: i for i, k in enumerate(self.activity_keys)} # methods self.methods = self.cs['ia'] self.method_index = {m: i for i, m in enumerate(self.methods)} self.rev_method_index = {i: m for i, m in enumerate(self.methods)} # previously: self.rev_method_index = {v: k for k, v in self.method_index.items()} # self.rev_method_index = {v: k for k, v in self.method_index.items()} self.func_unit_translation_dict = { str(bw.get_activity(list(func_unit.keys())[0])): func_unit for func_unit in self.func_units } if len(self.func_unit_translation_dict) != len(self.func_units): self.func_unit_translation_dict = {} for fu in self.func_units: act = bw.get_activity(next(iter(fu))) self.func_unit_translation_dict["{} {}".format(act, act[0])] = fu self.func_key_dict = { m: i for i, m in enumerate(self.func_unit_translation_dict.keys()) } self.func_key_list = list(self.func_key_dict.keys()) # GSA calculation variables self.A_matrices = list() self.B_matrices = list() self.CF_dict = defaultdict(list) self.parameter_exchanges = list() self.parameters = list() self.parameter_data = defaultdict(dict) self.results = list() self.lca = bw.LCA(demand=self.func_units_dict, method=self.methods[0])
#local files from pygsa.constants import * from pygsa.saindices.sobol_indices import sobol_indices ###1. LCA model bw.projects.set_current('Sobol indices') method = ('IPCC 2013', 'climate change', 'GWP 100a') ei = bw.Database('ecoinvent 3.5 cutoff') bs = bw.Database('biosphere3') demand_act = [act for act in ei if 'market for electricity, high voltage'==act['name'] and 'CH' in act['location']][0] demand_amt = 1 demand = {demand_act: demand_amt} lca = bw.LCA(demand,method) lca.lci() lca.lcia() q_low = (1-THREE_SIGMA_Q)/2 q_high = (1+THREE_SIGMA_Q)/2 A = lca.technosphere_matrix B = lca.biosphere_matrix c = sum(lca.characterization_matrix) lca.build_demand_array() d = lca.demand_array cB = c*B score_initial = cB*spsolve(A,d) #run it before MC to factorize matrix A
m for m in bw.methods if 'ReCiPe' in m[0] and 'Midpoint (E)' in m[0] and 'w/o LT' not in m[0] and ' no LT' not in m[0] and 'V1.13' in m[0] ] catalyst_production_db.write(catalyst_data) print('==========') Ni_Al2O3_prod = [ act for act in catalyst_production_db if 'Ni/Al2O3' in act['name'] ][0] Ni_Al2O3_prod_exc_list = [exc for exc in Ni_Al2O3_prod.exchanges()] method1 = recipe_mid[6] function_unit = {Ni_Al2O3_prod: 1} lca = bw.LCA(function_unit, method1) lca.lci() lca.lcia() print(lca.demand) print(lca.method) print('The {} process accounts for {:f} {}'.format( list(function_unit.keys())[0]['name'], lca.score, bw.methods.get(method1).get('unit'))) # out:The Ni/Al2O3 Production process accounts for 26.836102 kg CO2-Eq print('==========') ca = bwa.ContributionAnalysis() # print(ca.annotated_top_processes(lca, limit = 0.1, limit_type = 'percent')) # print('==========') print(lca.top_activities())
def run_analyses(self, demand_item, demand_item_code, amount=1, methods=[('IPCC 2013', 'climate change', 'GWP 100a')], top_processes=10, gt_cutoff=0.01, pie_cutoff=0.05): ready = self.setup_bw2() name = self.bw2_database_name if ready: if name in bw2.databases: del bw2.databases[name] print('Rewriting database ({}) ...'.format(name)) else: print('Writing database ({})...'.format( name)) # pragma: no cover new_db = bw2.Database(name) new_db.write(self.bw2_database) new_db.process() #print ('trying to get {}'.format(demand_item_code)) product_demand = new_db.get(demand_item_code) if product_demand is not False: fu = {product_demand: amount} parameter_sets = self.modelInstance.evaluated_parameter_sets ts = time.time() ts_format = datetime.datetime.fromtimestamp(ts).strftime( '%Y-%m-%d %H:%M:%S') result_dict = { 'settings': { 'pie_cutoff': pie_cutoff, 'methods': [str(method) for method in methods], 'method_names': [', '.join(method[1:]) for method in methods], 'method_units': [bw2.methods[method]['unit'] for method in methods], 'item': demand_item, 'item_code': demand_item_code, 'amount': amount, 'ps_names': [name for name in parameter_sets.keys()], 'item_unit': product_demand['unit'], 'timestamp': ts_format, } } result_sets = [] #for each parameter set in the model run the analysis for n, (parameter_set_name, parameter_set) in enumerate(parameter_sets.items()): # update the parameter_set values print('\nAnalysis {}\n'.format(n + 1)) self.update_exchange_amounts(new_db, parameter_set) initial_method = methods[0] # run the LCA lca = bw2.LCA(fu, initial_method) lca.lci(factorize=True) lca.lcia() ps_results = [] for method in methods: lca.switch_method(method) lca.redo_lcia(fu) unit = bw2.methods[method]['unit'] score = lca.score #print('Analysis for {} {} of {}, using {}'.format(amount, product_demand['unit'], product_demand['name'], method)) #print ('{:.3g} {}'.format(score, unit)) method_dict = { o[0]: o[1] for o in bw2.Method(method).load() } default_tag = "other" label = "lcopt_type" type_graph = [ recurse_tagged_database(key, amount, method_dict, lca, label, default_tag) for key, amount in fu.items() ] # type_result = aggregate_tagged_graph(type_graph) # for k,v in type_result.items(): # print('{}\t\t{}'.format(k,v)) label = "name" foreground_graph = [ recurse_tagged_database(key, amount, method_dict, lca, label, default_tag) for key, amount in fu.items() ] foreground_result = aggregate_tagged_graph( foreground_graph) #for k,v in foreground_result.items(): # print('{}\t\t{}'.format(k,v)) recursed_graph = self.multi_recurse( deepcopy(type_graph[0])) dropped_graph = self.drop_level_recurse( deepcopy(type_graph[0])) result_set = { 'ps_name': parameter_set_name, 'method': str(method), 'unit': unit, 'score': score, 'foreground_results': foreground_result, 'graph': recursed_graph, 'dropped_graph': dropped_graph, 'original_graph': str(type_graph[0]) } ps_results.append(result_set) result_sets.append(ps_results) result_dict['results'] = result_sets return result_dict
def contribution_LCA_to_df(datasets, cats=['CC', 'R_Total'], amount=1, names=['name', 'location']): """Calculate foreground contribution LCA of a list of datasets and return a multi-index dataframe. """ results = {} codes = {} index_dict = {} if datasets and cats: lca = bw.LCA({datasets[0]: 1}, method=lcia_methods[cats[0]]) lca.lci() lca.lcia() else: raise ValueError( "No datasets or impact categories found." + "Provide at least one dataset and one impact category.") for ds in datasets: index_dict[ds['code']] = tuple(ds[i] for i in names) for cat in cats: lca.switch_method(lcia_methods[cat]) cf_dict = dict(bw.Method(lcia_methods[cat]).load()) codes[cat] = {} results[cat] = {} for dataset in datasets: for exc in dataset.technosphere(): existing_value = 0 if (dataset['code'], exc.input['name']) in results[cat].keys(): existing_value = results[cat][(dataset['code'], exc.input['name'])] if exc['amount'] == 0: continue if exc['input'] in codes[cat]: results[cat][(dataset['code'], exc.input['name'])] = \ amount * codes[cat][exc['input']]*exc['amount'] + existing_value else: lca.redo_lcia({exc.input: exc['amount']}) results[cat][(dataset['code'],exc.input['name'])] = \ lca.score * amount + existing_value codes[cat][exc['input']] = (lca.score / exc['amount']) for exc in dataset.biosphere(): # Not all flows are characterized if exc.input in cf_dict: existing_value = 0 if (dataset['code'], exc.input['name']) in results[cat].keys(): existing_value = results[cat][(dataset['code'], exc.input['name'])] results[cat][(dataset['code'],exc.input['name'])] = \ amount * exc['amount'] * cf_dict[exc.input] + existing_value for cat in category_group: if cat in results.keys(): for key in results[cat].keys(): if 'CED' not in results.keys(): results['CED'] = {} try: results['CED'][key] += results[cat][key] except KeyError: results['CED'][key] = results[cat][key] del results[cat] return pd.DataFrame(results).unstack().sort_index(axis=1).rename( index=index_dict)
def _construct_lca(self): return bw.LCA(demand=self.func_units_dict, method=self.methods[0])
print(year) utils_update.dbUpdate_ElecAluLiq(bw_db_name=bw_db_name, year=year) utils_update.dbUpdate_EnerAlumina(bw_db_name=bw_db_name, year=year) utils_update.dbUpdate_cons_mix(bw_db_name=bw_db_name, year=year, mineral='bauxite') utils_update.dbUpdate_cons_mix(bw_db_name=bw_db_name, year=year, mineral='alumina') utils_update.dbUpdate_aluminum_global_production(bw_db_name=bw_db_name, year=year) for method in mining_recipe_method: Method = bw.Method(method) alu_cons_act = bw_db.get('market for consumption of aluminium') functional_unit = {alu_cons_act: 1} lca = bw.LCA(functional_unit, method) lca.lci( ) # Builds matrices, solves the system, generates an LCI matrix. lca.lcia() #Get activity contribution temp_dtf = pd.DataFrame( [(tmp_list[0], tmp_list[0] / lca.score, tmp_list[1], str(tmp_list[2])) for tmp_list in lca.top_activities()], columns=['Score', "Rel_score", 'Supply', 'Activity']) temp_dtf = temp_dtf.join( pd.DataFrame( { 'Year': year, 'Country': alu_cons_act['location'], 'Method_name': method[0], 'Midpoint': method[1],
def _construct_lca(self) -> bw.LCA: return bw.LCA(demand=self.func_units_dict, method=self.methods[0], presamples=[self.package.path])
def get_median_act(bw_db_name, name_to_include, name_to_exclude, unit, ia_method, location_keywords=None): ''' Function that return the median case of LCA scores of activiies specified by keywords Attributes: bw_db_name is the name of the Brightway database to update. name_to_include is a list of strings that should be individually contained in the activity name name_to_exclude is a list of strings that should not be individually contained in the activity name location_keywords is a list of strings that should be individually contained in the activity name None specified no location unit is the string of activity unit. ia_method is a bw Impact Assessment method ''' bw_db = bw.Database(bw_db_name) #Get the list of all potential activities if (location_keywords == None): act_list = [ act for act in bw_db if all(keyword in act['name'] for keyword in name_to_include) and all( keyword not in act['name'] for keyword in name_to_exclude) and unit in act['unit'] ] else: act_list = [ act for act in bw_db if all(keyword in act['name'] for keyword in name_to_include) and all( keyword not in act['name'] for keyword in name_to_exclude) and any(keyword == act['location'] for keyword in location_keywords) and unit in act['unit'] ] #Check the number of activities if len(act_list) == 0: raise KeyError("No activities found") else: dtf = pd.DataFrame() for act in act_list: try: lca_calc = bw.LCA({act: 1}, ia_method) except: raise StopIteration('LCA calculations do not work') lca_calc.lci() lca_calc.lcia() new_row = pd.DataFrame( { 'Activity': act['name'], 'Activity Location': act['location'], 'Score': lca_calc.score, 'Code': act['code'] }, index=[0]) dtf = dtf.append(new_row, ignore_index=True) dtf.sort_values(by='Score', inplace=True) #Get the index of the median. If odd number of activities, exact one. Otherwise, the closest lower score return { 'Median': dtf[dtf['Score'] <= dtf['Score'].median()].iloc[-1].Code }
def report_LDV_LCA(self): """ Report per-drivetrain impacts along the given dimension. Both per-pkm as well as total numbers are given. :return: a dataframe with impacts for the REMIND EDGE-T transport sector model. Levelized impacts (per pkm) are found in the column `score_pkm`, total impacts in `total_score`. :rtype: pandas.DataFrame """ df = self.data[self.data.Variable.isin(self.variables)] df.loc[:, "score_pkm"] = 0. df.loc[:, "score_pkm_direct"] = 0. # add methods dimension & score column methods_df = pd.DataFrame({"Method": self.methods, "score_pkm": 0.}) df = df.merge(methods_df, "outer") # on "score_pkm" df.set_index(["Year", "Region", "Variable", "Method"], inplace=True) start = time.time() # calc score for year in self.years: # find activities which at the moment do not depend # on regions db = bw.Database(eidb_label(self.model, self.scenario, year)) fleet_acts = [ a for a in db if a["name"].startswith( "transport, passenger car, fleet average") ] lca = bw.LCA({fleet_acts[0]: 1}) lca.lci() fleet_idxs = [lca.activity_dict[a.key] for a in fleet_acts] for region in self.regions: for var in (df.loc[( year, region)].index.get_level_values(0).unique()): demand = self._act_from_variable(var, db, year, region) if not demand: continue lca = bw.LCA(demand, method=self.methods[0]) # build inventories lca.lci() ## this is a workaround to correct for higher loadfactors in the LowD scenarios if "_LowD" in self.scenario: fct = max(1 - (year - 2020) / 15 * 0.15, 0.85) else: fct = 1. for method in self.methods: lca.switch_method(method) lca.lcia() df.at[(year, region, var, method), "score_pkm"] = lca.score * fct res_vec = np.squeeze( np.asarray( lca.characterized_inventory.sum(axis=0))) df.at[(year, region, var, method), "score_pkm_direct"] = \ np.sum(res_vec[fleet_idxs]) * fct print("Calculation took {} seconds.".format(time.time() - start)) df["total_score"] = df["value"] * df["score_pkm"] * 1e9 df["total_score_direct"] = df["value"] * df["score_pkm_direct"] * 1e9 return df[[ "total_score", "total_score_direct", "score_pkm", "score_pkm_direct" ]]