def delete_activity(self, data: Union[tuple, Iterator[tuple]]) -> None: """Use the given data to delete one or more activities from brightway2.""" activities = self._retrieve_activities(data) if any(len(act.upstream()) > 0 for act in activities): text = ( "Can't delete one or more activities. Some upstream process" " consumes their reference products. Please edit or delete " "these upstream exchanges first.") QtWidgets.QMessageBox.warning(self.window, "Not possible.", text) return # Iterate through the activities and: # - Close any open activity tabs, # - Delete any related parameters # - Delete the activity # - Clean the activity from the metadata. for act in activities: signals.close_activity_tab.emit(act.key) ParameterController.delete_activity_parameter(act.key) act.delete() AB_metadata.update_metadata(act.key) # After deletion, signal that the database has changed db = next(iter(activities)).get("database") bw.databases.set_modified(db) signals.database_changed.emit(db) signals.databases_changed.emit() signals.calculation_setup_changed.emit()
def new_activity(self, database_name: str) -> None: name, ok = QtWidgets.QInputDialog.getText( self.window, "Create new technosphere activity", "Please specify an activity name:" + " " * 10, ) if ok and name: data = { "name": name, "reference product": name, "unit": "unit", "type": "process" } new_act = bw.Database(database_name).new_activity( code=uuid.uuid4().hex, **data) new_act.save() production_exchange = new_act.new_exchange(input=new_act, amount=1, type="production") production_exchange.save() bw.databases.set_modified(database_name) AB_metadata.update_metadata(new_act.key) signals.open_activity_tab.emit(new_act.key) signals.database_changed.emit(database_name) signals.databases_changed.emit()
def modify_activity(key: tuple, field: str, value: object) -> None: activity = bw.get_activity(key) activity[field] = value activity.save() bw.databases.set_modified(key[0]) AB_metadata.update_metadata(key) signals.database_changed.emit(key[0])
def duplicate_activity(self, data: Union[tuple, Iterator[tuple]]) -> None: """Duplicates the selected activity in the same db, with a new BW code.""" # todo: add "copy of" (or similar) to name of activity for easy identification in new db # todo: some interface feedback so user knows the copy has succeeded activities = self._retrieve_activities(data) for act in activities: new_code = self.generate_copy_code(act.key) new_act = act.copy(new_code) # Update production exchanges for exc in new_act.production(): if exc.input.key == act.key: exc.input = new_act exc.save() # Update 'products' for product in new_act.get('products', []): if product.get('input') == act.key: product['input'] = new_act.key new_act.save() AB_metadata.update_metadata(new_act.key) signals.open_activity_tab.emit(new_act.key) db = next(iter(activities)).get("database") bw.databases.set_modified(db) signals.database_changed.emit(db) signals.databases_changed.emit()
def __init__(self, parent=None): super().__init__(parent=parent) self.database_name = None self.act_fields = lambda: AB_metadata.get_existing_fields( ["reference product", "name", "location", "unit"]) self.ef_fields = lambda: AB_metadata.get_existing_fields( ["name", "categories", "type", "unit"]) self.technosphere = True signals.database_selected.connect(self.sync) signals.database_changed.connect(self.check_database_changed)
def add_exchanges(self, from_keys: Iterator[tuple], to_key: tuple) -> None: activity = bw.get_activity(to_key) for key in from_keys: technosphere_db = bc.is_technosphere_db(key[0]) exc = activity.new_exchange(input=key, amount=1) if key == to_key: exc['type'] = 'production' elif technosphere_db is True: exc['type'] = 'technosphere' elif technosphere_db is False: exc['type'] = 'biosphere' else: exc['type'] = 'unknown' exc.save() bw.databases.set_modified(to_key[0]) AB_metadata.update_metadata(to_key) signals.database_changed.emit(to_key[0])
def generate_copy_code(key: tuple) -> str: db, code = key metadata = AB_metadata.get_database_metadata(db) if '_copy' in code: code = code.split('_copy')[0] copies = metadata["key"].apply( lambda x: x[1] if code in x[1] and "_copy" in x[ 1] else None).dropna().to_list() if not metadata.empty else [] if not copies: return "{}_copy1".format(code) n = max((int(c.split('_copy')[1]) for c in copies)) return "{}_copy{}".format(code, n + 1)
def df_from_metadata(self, db_name: str) -> pd.DataFrame: """ Take the given database name and return the complete subset of that database from the metadata. The fields are used to prune the dataset of unused columns. """ df = AB_metadata.get_database_metadata(db_name) # New / empty database? Shortcut the sorting / structuring process if df.empty: return df df = df.loc[:, self.fields + ["key"]] df.columns = [bc.bw_keys_to_AB_names.get(c, c) for c in self.fields] + ["key"] # Sort dataframe on first column (activity name, usually) # while ignoring case sensitivity sort_field = df.columns[0] df = df.iloc[df[sort_field].str.lower().argsort()] sort_field_index = df.columns.to_list().index(sort_field) self.parent().horizontalHeader().setSortIndicator( sort_field_index, Qt.AscendingOrder) return df
def _copy_activity(target: str, act: Activity) -> tuple: new_code = ActivityController.generate_copy_code((target, act['code'])) new_key = (target, new_code) act.copy(code=new_code, database=target) AB_metadata.update_metadata(new_key) return new_key