Skip to content

Commit c44cb36

Browse files
authored
Branch 2.6.2 (#479)
* Improve parameter deleting (#478) * Delete database group after deleting database * Clean up activity group on activity delete * Try and delete group if activity param is removed * Add controller method for clearing activity param * Trigger removal of parameter with signal * Recalculate after editing parameter * Recalculate even if formula is the same * Drop unused method for recalculating * Ensure delete goes before select * Use applymap instead of apply (#476)
1 parent 0b19c50 commit c44cb36

File tree

5 files changed

+56
-35
lines changed

5 files changed

+56
-35
lines changed

activity_browser/app/bwutils/superstructure/excel.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,7 @@ def import_from_excel(document_path: Union[str, Path], import_sheet: int = 1):
7878
raise ValueError("Missing required column(s) for superstructure: {}".format(diff.to_list()))
7979

8080
# Convert specific columns that may have tuples as strings
81-
data["from categories"] = data["from categories"].apply(lambda x: convert_tuple_str(x))
82-
data["from key"] = data["from key"].apply(lambda x: convert_tuple_str(x))
83-
data["to categories"] = data["to categories"].apply(lambda x: convert_tuple_str(x))
84-
data["to key"] = data["to key"].apply(lambda x: convert_tuple_str(x))
81+
columns = ["from categories", "from key", "to categories", "to key"]
82+
data.loc[:, columns] = data[columns].applymap(convert_tuple_str)
83+
8584
return data

activity_browser/app/controller.py

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from typing import Iterable, Optional
44

55
import brightway2 as bw
6-
from bw2data.parameters import ActivityParameter
6+
from bw2data.parameters import ActivityParameter, Group
77
from PySide2 import QtWidgets
88
from PySide2.QtCore import QObject, Slot
99
from bw2data.backends.peewee import sqlite3_lci_db
@@ -79,6 +79,7 @@ def connect_signals(self):
7979
signals.parameter_modified.connect(self.modify_parameter)
8080
signals.parameter_uncertainty_modified.connect(self.modify_parameter_uncertainty)
8181
signals.parameter_pedigree_modified.connect(self.modify_parameter_pedigree)
82+
signals.clear_activity_parameter.connect(self.clear_broken_activity_parameter)
8283
# Calculation Setups
8384
signals.new_calculation_setup.connect(self.new_calculation_setup)
8485
signals.rename_calculation_setup.connect(self.rename_calculation_setup)
@@ -267,7 +268,8 @@ def copy_database(self, name, parent):
267268
except ValueError as e:
268269
QtWidgets.QMessageBox.information(parent, "Not possible", str(e))
269270

270-
def delete_database(self, name):
271+
@Slot(str, name="deleteDatabase")
272+
def delete_database(self, name: str) -> None:
271273
ok = QtWidgets.QMessageBox.question(
272274
None,
273275
"Delete database?",
@@ -277,6 +279,7 @@ def delete_database(self, name):
277279
if ok == QtWidgets.QMessageBox.Yes:
278280
project_settings.remove_db(name)
279281
del bw.databases[name]
282+
Group.delete().where(Group.name == name).execute()
280283
self.change_project(bw.projects.current, reload=True)
281284

282285
@Slot(str, QObject, name="relinkDatabase")
@@ -360,7 +363,8 @@ def new_activity(database_name: str) -> None:
360363
signals.database_changed.emit(database_name)
361364
signals.databases_changed.emit()
362365

363-
def delete_activity(self, key):
366+
@Slot(tuple, name="deleteActivity")
367+
def delete_activity(self, key: tuple) -> None:
364368
act = bw.get_activity(key)
365369
nu = len(act.upstream())
366370
if nu:
@@ -583,19 +587,27 @@ def modify_parameter(param: ParameterBase, field: str, value: object) -> None:
583587
else:
584588
param.data[field] = value
585589
param.save()
590+
bw.parameters.recalculate()
586591
signals.parameters_changed.emit()
587592

588593
@staticmethod
589594
def delete_activity_parameter(key: tuple) -> None:
590595
"""Remove all activity parameters and underlying exchange parameters
591596
for the given key.
592597
"""
593-
query = ActivityParameter.select(ActivityParameter.group).where(
594-
ActivityParameter.database == key[0],
595-
ActivityParameter.code == key[1],
596-
)
597-
for p in query.iterator():
598-
bw.parameters.remove_from_group(p.group, key)
598+
query = (ActivityParameter
599+
.select(ActivityParameter.group)
600+
.where(ActivityParameter.database == key[0],
601+
ActivityParameter.code == key[1])
602+
.tuples())
603+
groups = set(p[0] for p in query.iterator())
604+
for group in groups:
605+
bw.parameters.remove_from_group(group, key)
606+
exists = (ActivityParameter.select()
607+
.where(ActivityParameter.group == group)
608+
.exists())
609+
if not exists:
610+
Group.delete().where(Group.name == group).execute()
599611
bw.parameters.recalculate()
600612
signals.parameters_changed.emit()
601613

@@ -618,6 +630,28 @@ def modify_parameter_pedigree(param: ParameterBase, pedigree: dict) -> None:
618630
param.save()
619631
signals.parameters_changed.emit()
620632

633+
@staticmethod
634+
@Slot(str, str, str, name="deleteRemnantParameters")
635+
def clear_broken_activity_parameter(database: str, code: str, group: str) -> None:
636+
"""Take the given information and attempt to remove all of the
637+
downstream parameter information.
638+
"""
639+
with bw.parameters.db.atomic() as txn:
640+
bw.parameters.remove_exchanges_from_group(group, None, False)
641+
ActivityParameter.delete().where(
642+
ActivityParameter.database == database,
643+
ActivityParameter.code == code
644+
).execute()
645+
# Do commit to ensure .exists() call does not include deleted params
646+
txn.commit()
647+
exists = (ActivityParameter.select()
648+
.where(ActivityParameter.group == group)
649+
.exists())
650+
if not exists:
651+
# Also clear Group if it is not in use anymore
652+
Group.delete().where(Group.name == group).execute()
653+
654+
# MetaDataStore
621655
@staticmethod
622656
@Slot(name="triggerMetadataReset")
623657
def reset_metadata() -> None:
@@ -633,6 +667,7 @@ def update_metadata(key: tuple) -> None:
633667
def print_convenience_information(db_name: str) -> None:
634668
AB_metadata.print_convenience_information(db_name)
635669

670+
# Presamples
636671
@staticmethod
637672
@Slot(str, name="removePresamplesPackage")
638673
def remove_presamples_package(name_id: str) -> None:

activity_browser/app/signals.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ class Signals(QObject):
7171
parameter_pedigree_modified = Signal(object, object)
7272
parameter_scenario_sync = Signal(int, object)
7373
parameter_superstructure_built = Signal(int, object)
74+
clear_activity_parameter = Signal(str, str, str)
7475

7576
# Presamples
7677
presample_package_created = Signal(str)

activity_browser/app/ui/tables/delegates/formula.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,4 @@ def setModelData(self, editor: QtWidgets.QWidget, model: QtCore.QAbstractItemMod
247247
if dialog.result() == QtWidgets.QDialog.Rejected:
248248
# Cancel was clicked, do not store anything.
249249
return
250-
if model.data(index, QtCore.Qt.DisplayRole) == dialog.formula:
251-
# The text in the dialog is the same as what is already there.
252-
return
253250
model.setData(index, dialog.formula, QtCore.Qt.EditRole)

activity_browser/app/ui/tables/parameters.py

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,10 @@ def parse_parameter(cls, parameter) -> dict:
438438
act = bw.get_activity(row["key"])
439439
except:
440440
# Can occur if an activity parameter exists for a removed activity.
441-
print("Activity {} no longer exists, ignoring parameter.".format(row["key"]))
441+
print("Activity {} no longer exists, removing parameter.".format(row["key"]))
442+
signals.clear_activity_parameter.emit(
443+
parameter.database, parameter.code, parameter.group
444+
)
442445
return {}
443446
row["product"] = act.get("reference product") or act.get("name")
444447
row["activity"] = act.get("name")
@@ -581,10 +584,11 @@ def delete_parameter(self, proxy) -> None:
581584
group = self.get_current_group(proxy)
582585
bw.parameters.remove_from_group(group, act)
583586
# Also clear the group if there are no more parameters in it
584-
if not (ActivityParameter.select()
585-
.where(ActivityParameter.group == group).exists()):
587+
exists = (ActivityParameter.select()
588+
.where(ActivityParameter.group == group).exists())
589+
if not exists:
586590
with bw.parameters.db.atomic():
587-
Group.get(name=group).delete_instance()
591+
Group.delete().where(Group.name == group).execute()
588592

589593
bw.parameters.recalculate()
590594
signals.parameters_changed.emit()
@@ -681,18 +685,3 @@ def parameterize_exchanges(self, key: tuple) -> None:
681685
bw.parameters.add_exchanges_to_group(group, act)
682686
ActivityParameter.recalculate_exchanges(group)
683687
signals.parameters_changed.emit()
684-
685-
@staticmethod
686-
@Slot()
687-
def recalculate_exchanges():
688-
""" Will iterate through all activity parameters and rerun the
689-
formula interpretation for all exchanges.
690-
"""
691-
for param in ActivityParameter.select().iterator():
692-
try:
693-
act = bw.get_activity((param.database, param.code))
694-
bw.parameters.add_exchanges_to_group(param.group, act)
695-
ActivityParameter.recalculate_exchanges(param.group)
696-
except:
697-
continue
698-
signals.parameters_changed.emit()

0 commit comments

Comments
 (0)