Assessment (cost and LCA)¶
The assessment layer computes cost and life-cycle impact as functions of a solved, verified state (see Cost estimation and LCA). It is a Python library layer: the CLI, HTTP and MCP interfaces do not offer it yet. A typical sequence, as in the cost and climate impact example:
from openflowsheet.application.revision_binding import bind_revision_flowsheet
from openflowsheet.assessment.program import AssessmentProgram
from openflowsheet.assessment.spec import load_assessment
from openflowsheet.assessment.views import view_of
from openflowsheet.canonical import state_sha256
binding = bind_revision_flowsheet(revision) # the solved revision document
program = AssessmentProgram.build(
view_of(binding.flowsheet), binding.spec, load_assessment(document), state
)
report = program.report(state, state_sha256=state_sha256(state, binding.spec.variable_ids))
revision and state are the revision.json and solution-state.json of the run's replay
bundle. Unsupported requests come back as a typed Refusal; they are not raised.
The document¶
load_assessment ¶
load_assessment(
source: Mapping[str, Any] | str | Path,
) -> AssessmentSpec
An AssessmentSpec from a document or a JSON file; AssessmentDocumentError otherwise.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
Mapping[str, Any] | str | Path
|
The assessment document ( |
required |
Returns:
| Type | Description |
|---|---|
AssessmentSpec
|
The validated document and its identity, |
Raises:
| Type | Description |
|---|---|
AssessmentDocumentError
|
When the document has no canonical JSON form or does not validate against the schema;
|
AssessmentSpec
dataclass
¶
AssessmentSpec(
document: Mapping[str, Any], assessment_sha256: str
)
A validated assessment document and its identity. The document is a private deep copy.
section ¶
section(name: str) -> Any
A top-level section, or None when the document does not have it.
AssessmentDocumentError ¶
AssessmentDocumentError(errors: list[str])
Bases: ValueError
The document is not a valid, canonical assessment; errors lists every reason.
The flowsheet's view¶
view_of ¶
view_of(
flowsheet: RevisionFlowsheet | Syn001Flowsheet,
) -> FlowsheetView
The assessment's view of a bound flowsheet.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
flowsheet
|
RevisionFlowsheet | Syn001Flowsheet
|
A bound revision flowsheet ( |
required |
Returns:
| Type | Description |
|---|---|
FlowsheetView
|
The components, the property provider, the units with their ports and connections, and the molar masses: everything the contributors read, and nothing they could change. |
Raises:
| Type | Description |
|---|---|
TypeError
|
For any other kind of flowsheet. |
The program¶
AssessmentProgram ¶
AssessmentProgram(
*,
ctx: BuildContext,
contributors: tuple[Contributor, ...],
rows: tuple[_Row, ...],
output_count: int,
theta: tuple[Theta, ...],
blocks: tuple[
tuple[PropertyBlock, tuple[str, ...]], ...
],
entries: tuple[RegimeEntry, ...],
plans: Mapping[str, ContributionPlan],
)
One assessment over one host at one held regime (§4.1, §4.2.1).
The outputs (sizes, costs, inventory, impacts, derived ratios) are rows of one functional
ProblemSpec over the host's variables, compiled by the existing compiler and never part of
the host's CompiledProblem. Build one with AssessmentProgram.build; then evaluate,
linearize and report it at a state.
build
classmethod
¶
build(
view: FlowsheetView,
host_spec: ProblemSpec,
spec: AssessmentSpec,
state: Mapping[str, float],
regime: Regime | None = None,
*,
contributors: Sequence[Contributor] | None = None,
) -> AssessmentProgram | Refusal
Plan every contributor at state and compile the functional spec (§4.2.1).
regime=None selects by the rule at state. A given regime is held: every one of its
entries must be one the program has, and every admissibility row must be ≥ −τ_feas at
state, else ASSESSMENT_REGIME_INADMISSIBLE. contributors defaults to the three of
CONTRIBUTOR_ORDER; a document section whose contributor is not among them is refused
ASSESSMENT_CONTRIBUTOR_MISSING(<section>), never silently ignored (R-869).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
view
|
FlowsheetView
|
The flowsheet's view, |
required |
host_spec
|
ProblemSpec
|
The host's problem specification (a revision binding's |
required |
spec
|
AssessmentSpec
|
The assessment document, |
required |
state
|
Mapping[str, float]
|
The solved state by variable id, normally a certified solution. |
required |
regime
|
Regime | None
|
A regime to hold, or |
None
|
contributors
|
Sequence[Contributor] | None
|
The contributors to plan; by default the registered cost, LCA and derived ones. |
None
|
Returns:
| Type | Description |
|---|---|
AssessmentProgram or Refusal
|
The program, or a typed refusal; an unsupported request is never raised. |
evaluate ¶
evaluate(
x: Mapping[str, float],
decisions: Mapping[str, float] = MappingProxyType({}),
*,
domain_guard: bool = True,
) -> Mapping[str, float] | Refusal
Every output and admissibility row at (x, d) on the float path (§4.2.1).
Raises TwinEvaluationError where a value cannot be evaluated (§4.2.3), including a
domain row ≤ 0: METRIC_UNDEFINED(<output_id>) at every state (§4.7.5 erratum, R-868).
domain_guard=False is the report's alone: it nulls each undefined output itself and
reports the others (§4.9).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Mapping[str, float]
|
The state by host variable id. |
required |
decisions
|
Mapping[str, float]
|
Host pinned inputs at other values than the program's; an assessment parameter is
refused |
MappingProxyType({})
|
domain_guard
|
bool
|
Raise on an undefined output (see above); |
True
|
Returns:
| Type | Description |
|---|---|
Mapping[str, float] or Refusal
|
Every output and every admissibility row ( |
linearize ¶
linearize(
x: Mapping[str, float],
decisions: Mapping[str, float],
outputs: Sequence[str],
symbolic: Sequence[str] = (),
) -> Linearization | Refusal
Values (twin) of every row, and ∂(outputs)/∂x (outputs x host variable ids) and
∂(outputs)/∂p (outputs x symbolic), at (x, d). The decisions are symbols of the twin
whether or not they are requested, so the graph is the one the NLP differentiates.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Mapping[str, float]
|
The state by host variable id. |
required |
decisions
|
Mapping[str, float]
|
Host pinned inputs at other values than the program's (may be empty). |
required |
outputs
|
Sequence[str]
|
The output ids to differentiate. |
required |
symbolic
|
Sequence[str]
|
Host pinned inputs or assessment parameters ( |
()
|
Returns:
| Type | Description |
|---|---|
Linearization or Refusal
|
|
report ¶
report(
x: Mapping[str, float],
*,
state_sha256: str,
uncertainty: bool = True,
) -> dict[str, Any]
The assessment report at x (§4.2.1, §4.9, §4.11): a document valid against
assessment-report.schema.json. Built by assessment.report.build_report.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Mapping[str, float]
|
The state by host variable id. |
required |
state_sha256
|
str
|
The state's identity ( |
required |
uncertainty
|
bool
|
Whether to propagate the declared input ranges (first-order interval and σ). |
True
|
Returns:
| Type | Description |
|---|---|
dict
|
The report: status, regime, items, capital, operating and annual figures, LCA inventory and impacts, uncertainty, limitations, refusals and the evidence statement. |
select ¶
select(
x: Mapping[str, float],
decisions: Mapping[str, float] = MappingProxyType({}),
*,
release: Sequence[str] = (),
) -> Regime
The regime at x (§4.3.2): the held choice of every entry whose admissibility rows are
≥ −τ_feas at x, the rule for the others. A held regime that cannot be evaluated at x
is released whole.
decisions are host pins at other values than the program's (a study's candidate,
§4.10.3 V7): the rows and the rule then read them. release gives entries to the rule
whatever their rows — V7's dormancy entries, which have none (§4.3.1).
Refusal
dataclass
¶
Refusal(
code: str,
target: str = "",
detail: str = "",
kind: Literal["refusal", "unsupported"] = "refusal",
)
A typed refusal (or an unsupported result): never an exception to the caller (§4.12).
Limitation
dataclass
¶
Limitation(
code: str,
target: str = "",
detail: Mapping[str, Any] = dict(),
)
A typed limitation of a computed result (§4.12).
build_report ¶
build_report(
program: AssessmentProgram,
x: Mapping[str, float],
*,
state_sha256: str,
uncertainty: bool = True,
) -> dict[str, Any]
The report at x (§4.11); provenance is outside every hash.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
program
|
AssessmentProgram
|
The assessment program. |
required |
x
|
Mapping[str, float]
|
The state by host variable id. |
required |
state_sha256
|
str
|
The state's identity, recorded in the report. |
required |
uncertainty
|
bool
|
Whether to propagate the declared input ranges. |
True
|
Returns:
| Type | Description |
|---|---|
dict
|
A document valid against |
Sensitivities¶
assessment_sensitivity ¶
assessment_sensitivity(
program: AssessmentProgram,
host: SensitivityHost,
request: SensitivityRequest,
state: NDArray[float64],
outputs: Sequence[str],
certificate: CertificateEvidence | None = None,
*,
scales: Mapping[str, float] | None = None,
splits: Sequence[SplitRegime] = (),
) -> AssessmentSensitivity
§4.10.1: dy/dp of the assessment outputs (ids without the prefix) at the certified
state (in host.spec.variable_ids order) for request's parameters and mode.
scales gives an output's scale; by default max(|y(x*)|, 1) (§4.10.2's output scale). A
refusal of program.linearize (an unavailable or unknown output) is returned with no host
run. Raises ValueError when the program's host variables are not the host's.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
program
|
AssessmentProgram
|
The assessment program, built over the same host problem. |
required |
host
|
SensitivityHost
|
The sensitivity host, e.g. |
required |
request
|
SensitivityRequest
|
The parameters, the host outputs and the mode (forward, adjoint or both). |
required |
state
|
NDArray[float64]
|
The certified state, in |
required |
outputs
|
Sequence[str]
|
The assessment output ids, without the |
required |
certificate
|
CertificateEvidence | None
|
The certificate's evidence, passed to the host's qualification. |
None
|
scales
|
Mapping[str, float] | None
|
Output scales; by default |
None
|
splits
|
Sequence[SplitRegime]
|
Split regimes, passed to the host's evaluation. |
()
|
Returns:
| Type | Description |
|---|---|
AssessmentSensitivity
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
When the program was built over a different host problem. |
AssessmentSensitivity
dataclass
¶
AssessmentSensitivity(
outputs: tuple[str, ...],
parameter_ids: tuple[str, ...],
scales: Mapping[str, float],
dependence: Mapping[str, Dependence],
forward: SensitivityBlock | None,
adjoint: SensitivityBlock | None,
base: SensitivityResult | None,
refusals: tuple[Refusal, ...] = (),
regime_bounds_active: tuple[
tuple[str, float], ...
] = (),
regime_slack: Mapping[str, float | None] = dict(),
limitations: tuple[Limitation, ...] = (),
)
dy/dp of the requested assessment outputs (rows) over the request's parameters
(columns), forward and/or adjoint as the request's mode; None where the host's column, or
the whole request, is refused. base is the host's result for the augmented request (its
own outputs first, then assessment:<id> for every state-dependent output).
revision_sensitivity_host ¶
revision_sensitivity_host(
flowsheet: Any, state: Mapping[str, float]
) -> SensitivityHost
syn001.host_of for a RevisionFlowsheet: flowsheet.spec(), its compiled problem, K03
scales from the spec's declared kinds, and the alias rows eliminate_alias_rows removes at
state with the pressure-shifted second state of the certificate (verify/certificate.py;
without a second state the elimination is structural, as there).
trf_objective_from_assessment ¶
trf_objective_from_assessment(
program: AssessmentProgram, output_id: str
) -> Refusal
The only route from an assessment output to a trust-region objective (§4.10.4). Day one:
UNSUPPORTED(ASSESSMENT_OUTPUT_IN_TRF), before anything is built or solved (A37; §7 Q1).
Building unit-score tables (the lca extra)¶
These functions run only where bw2data and bw2calc are installed; without them each returns
UNSUPPORTED(LCA_ENGINE_UNAVAILABLE). They never run inside a solve, an optimisation or a replay.
build_unit_score_table ¶
build_unit_score_table(
project: str,
activities: Sequence[tuple[str, Sequence[str]]],
categories: Sequence[tuple[str, Sequence[str]]],
rights: Mapping[str, str],
*,
table_id: str,
si_per_unit: Mapping[str, float] | None = None,
) -> dict[str, Any] | Refusal
A unit-score-table-v1 of q_{m,k} for activities [(activity_id, key)] and
categories [(category_id, method)] in project (§4.8.4).
si_per_unit gives an activity's unit in SI where SI_PER_UNIT does not know its unit. A
key or a method the project lacks is refused LCA_ACTIVITY_UNKNOWN (never raised).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project
|
str
|
The Brightway project, prepared by the user (no database is downloaded). |
required |
activities
|
Sequence[tuple[str, Sequence[str]]]
|
|
required |
categories
|
Sequence[tuple[str, Sequence[str]]]
|
|
required |
rights
|
Mapping[str, str]
|
The table's rights: |
required |
table_id
|
str
|
The new table's id. |
required |
si_per_unit
|
Mapping[str, float] | None
|
SI amount per activity unit, for units the adapter does not know. |
None
|
Returns:
| Type | Description |
|---|---|
dict or Refusal
|
A |
build_direct_factor_table ¶
build_direct_factor_table(
project: str,
method: tuple[str, Sequence[str]],
flows: Sequence[tuple[str, Sequence[str]]],
rights: Mapping[str, str],
*,
table_id: str,
source: Mapping[str, Any] | None = None,
) -> dict[str, Any] | Refusal
A direct-factor-table-v1 of method (category_id, method)'s characterisation factors
for flows [(flow_id, biosphere key)]; a flow the method does not characterise gets 0.0.
foreground_check ¶
foreground_check(
project: str,
exchanges: Sequence[tuple[Sequence[str], float]],
emissions: Sequence[tuple[Sequence[str], float]],
method: Sequence[str],
) -> float | Refusal
Brightway's score of one foreground activity that consumes exchanges [(key, a_k)]
(activity units; negative for generation or substitution) and emits emissions
[(biosphere key, kg)], characterised by method (A25). Runs in a scratch copy of project,
which is deleted afterwards.