Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .cursor/rules/always.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ alwaysApply: true
- Preserve deferred-import patterns on hot paths (`ADR-0002`).
- Do not invent or harden a plugin API (placeholder in `AGENTS.md` until redesigned).
- Prefer small, localized diffs; add/update tests for stateful behavior.
- **Never create a git commit unless the user explicitly asks to commit in that message.** Skills that say “commit when done” (e.g. `/implement`) do **not** override this — finish the work, leave changes uncommitted, and wait for an explicit commit request. Do not stage-and-commit “to finish the task,” “because the skill says so,” or “so code-review has a SHA.”
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ Agents should not assume Linux-only or a single Python version. Details live in
- When changing stateful behavior (settings, databases, signals), update or add tests and keep the same signal contracts.
- Preserve deferred-import and `mod/` patching patterns unless an ADR says otherwise.
- Do not invent plugin APIs (see placeholder above).
- **Never create a git commit unless the user explicitly asks to commit.** Slash skills that mention committing (e.g. `/implement`) do not override this — leave changes uncommitted until the user requests a commit.

## Useful references

Expand Down
10 changes: 9 additions & 1 deletion CONTEXT.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ The quantified output (or input in case of a waste treatment system) of the prod

### Calculation setup (CS)

A named set of functional unit(s) and LCIA method(s) used to run LCA / multi-LCA / Monte Carlo. Managed under calculation-setup UI and `app` actions. It can also additionaly include scenarios as a third element in the "Scenario" LCA mode.
A named set of functional unit(s) and LCIA method(s) used to run LCA / multi-LCA / Monte Carlo. Managed under calculation-setup UI and `app` actions. It can also additionaly include scenarios as a third element in the "Scenario" LCA mode. The CS page always opens in **Standard** mode; switching to **Scenario** mode may reload persisted scenario files (with a loading indication). Scenario file paths, combine mode, and the included scenario-combinations set may be stored on the CS.

### LCIA method / impact category

Expand Down Expand Up @@ -74,6 +74,14 @@ Analysis of how uncertain inputs drive output variance (e.g. SALib-based), based

An LCA calculation that also considers multiple scenarios for inventory data (based on the superstructure approach). See `activity_browser/bwutils/superstructure/`.

### Scenario name

The string identifier of a scenario column in a scenario difference file (or in a combined scenario table). Always a string — file importers coerce numeric-looking headers (e.g. Excel `2025`) with `str(...)`. When scenarios from multiple files are combined (product), the combined scenario name is the file-order join of the parts with ` | ` (e.g. `A` and `X` → `A | X`). _Avoid_: scenario header (as a typed value), scenario label when meaning the column identity.

### Scenario-combinations list

The list of product-combined scenario names from two or more loaded scenario difference files (e.g. `A | X`), each with an include checkbox. Shown beside the per-file scenario lists in the calculation setup when 2+ files are loaded under Combine. Together with per-file scenario checkboxes it supports coarse (row/column/slice) and fine (cell) inclusion. Under **Extend**, there is no combinations list: inclusion is by shared scenario name, and checkboxes for the same name stay in sync across files. _Avoid_: scenario-selection-matrix (deferred 2D editor), SS-matrix, combiner matrix.

### Metadata store

Cached tabular metadata for fast UI search and display (`app.metadata` / `activity_browser.bwutils.metadata`). Synced via `app.signals.metadata` and related meta signals; tests often wait for the metadata loader.
Expand Down
12 changes: 12 additions & 0 deletions activity_browser/app/actions/calculation_setup/cs_calculate.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,18 @@ def run(cs_name: str, scenario_data: pd.DataFrame = None):
f"Calculation setup '{cs_name}' has no active impact categories."
)

if scenario_data is not None and (
scenario_data.empty or len(scenario_data.columns) == 0
):
QtWidgets.QMessageBox.warning(
app.main_window,
"No scenarios selected",
"Select at least one scenario before calculating.\n\n"
"Use the checkboxes on the scenario files, or the combinations "
"list when combining multiple files.",
)
return

dialog = CalculationDialog(cs_name, app.main_window)
dialog.show()
app.application.thread().eventDispatcher().processEvents(QtCore.QEventLoop.ProcessEventsFlag.AllEvents)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from loguru import logger
import copy

from qtpy import QtWidgets

Expand Down Expand Up @@ -44,6 +45,6 @@ def run(cs_name: str):
)
return

bd.calculation_setups[new_name] = bd.calculation_setups[cs_name].copy()
bd.calculation_setups[new_name] = copy.deepcopy(bd.calculation_setups[cs_name])
logger.info(f"Copied calculation setup {cs_name} as {new_name}")
CSOpen.run(new_name)
3 changes: 2 additions & 1 deletion activity_browser/app/actions/calculation_setup/cs_rename.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from loguru import logger
import copy

from qtpy import QtWidgets

Expand Down Expand Up @@ -44,6 +45,6 @@ def run(cs_name: str, new_name: str = None):
return

# instruct the CalculationSetupController to rename the CS to the new name
bd.calculation_setups[new_name] = bd.calculation_setups[cs_name].copy()
bd.calculation_setups[new_name] = copy.deepcopy(bd.calculation_setups[cs_name])
del bd.calculation_setups[cs_name]
logger.info(f"Renamed calculation setup from {cs_name} to {new_name}")
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ def type_switch(self, calculation_type: str):
self.scenario_section.hide()
elif calculation_type == "Scenario":
self.scenario_section.show()
self.scenario_section.load_persisted_scenarios()
else:
raise ValueError(f"Unknown calculation type: {calculation_type}")

Expand Down
Loading
Loading