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
4 changes: 2 additions & 2 deletions bedrock/analysis/electricity/class_prices/compare_paths.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from bedrock.transform.eeio.cornerstone_disagg_pipeline import (
MixedUnitEfResult,
compute_mixed_unit_ef_vectors,
table_2_4_prices_cents_kwh,
electricity_end_use_retail_prices_cents_kwh,
)
from bedrock.transform.eeio.derived_cornerstone import (
derive_cornerstone_Aq_scaled,
Expand All @@ -31,7 +31,7 @@ class ClassPricesComparison:

def _equal_prices_from_table() -> dict[str, float]:
cfg = get_usa_config()
prices = table_2_4_prices_cents_kwh(cfg.usa_ghg_data_year)
prices = electricity_end_use_retail_prices_cents_kwh(cfg.usa_ghg_data_year)
total = float(prices['Total'])
return {k: total for k in prices}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
from bedrock.analysis.electricity.d_85.disagg_weights import (
build_ugo_col_table83_row_intersection_matrix,
)
from bedrock.analysis.electricity.d_85.eia_inputs import table_2_4_prices_cents_kwh
from bedrock.analysis.electricity.d_85.eia_inputs import (
electricity_end_use_retail_prices_cents_kwh,
)
from bedrock.transform.eeio.electricity_disaggregation import ELECTRICITY_AGGREGATE
from bedrock.utils.schemas.cornerstone_schemas import ELECTRICITY_DISAGG_SECTORS

Expand Down Expand Up @@ -92,7 +94,7 @@ def test_t83_production_diag_step2_uses_table83_weights(


@mock.patch(
'bedrock.analysis.electricity.d_85.disagg_scenarios.table_2_4_prices_cents_kwh'
'bedrock.analysis.electricity.d_85.disagg_scenarios.electricity_end_use_retail_prices_cents_kwh'
)
@mock.patch('bedrock.analysis.electricity.d_85.disagg_scenarios.build_end_use_map')
@mock.patch('bedrock.analysis.electricity.d_85.disagg_scenarios.ugo305_go_weights')
Expand All @@ -109,7 +111,7 @@ def test_p24_weights_sum_to_one_per_column(
checkpoint_mock.return_value = (V, Udom, Uimp, VA, Y)
ugo_mock.return_value = pd.Series({'221110': 0.34, '221121': 0.04, '221122': 0.62})
map_mock.return_value = {'541000': 'Commercial', 'F01000': 'Residential'}
prices_mock.return_value = table_2_4_prices_cents_kwh(
prices_mock.return_value = electricity_end_use_retail_prices_cents_kwh(
2017, fba=mock_fba_table83_table24()
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import pytest

from bedrock.analysis.electricity.d_85.eia_inputs import (
table_2_4_prices_cents_kwh,
electricity_end_use_retail_prices_cents_kwh,
table_8_3_gtd_expenses_musd,
table_8_3_purchased_power_gtd_expenses_musd,
)
Expand All @@ -28,8 +28,8 @@ def test_table_8_3_purchased_power_gtd_expenses_musd(mock_fba: pd.DataFrame) ->
assert out['Distribution'] == pytest.approx(4358.0)


def test_table_2_4_prices_cents_kwh(mock_fba: pd.DataFrame) -> None:
prices = table_2_4_prices_cents_kwh(2017, fba=mock_fba)
def test_electricity_end_use_retail_prices_cents_kwh(mock_fba: pd.DataFrame) -> None:
prices = electricity_end_use_retail_prices_cents_kwh(2017, fba=mock_fba)
assert prices['Residential'] == pytest.approx(12.89)
assert prices['Total'] == pytest.approx(10.54)

Expand Down
6 changes: 4 additions & 2 deletions bedrock/analysis/electricity/d_85/disagg_scenarios.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
table83_purchased_power_weights,
ugo305_go_weights,
)
from bedrock.analysis.electricity.d_85.eia_inputs import table_2_4_prices_cents_kwh
from bedrock.analysis.electricity.d_85.eia_inputs import (
electricity_end_use_retail_prices_cents_kwh,
)
from bedrock.analysis.electricity.d_85.end_use_mapping import (
build_end_use_map,
build_price_tilt_weights_by_column,
Expand Down Expand Up @@ -326,7 +328,7 @@ def _weights_t83_purchased_power_diag_compensated() -> ScenarioWeights:

def _weights_p24(price_year: int) -> ScenarioWeights:
w_ugo = ugo305_go_weights()
raw_prices = table_2_4_prices_cents_kwh(price_year)
raw_prices = electricity_end_use_retail_prices_cents_kwh(price_year)
prices: dict[str, float] = {str(k): float(v) for k, v in raw_prices.items()}
end_use_map = build_end_use_map()
_, Udom, Uimp, _, Y = derive_post_reallocation_checkpoint()
Expand Down
4 changes: 2 additions & 2 deletions bedrock/analysis/electricity/d_85/eia_inputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
TABLE_2_4_DESCRIPTION,
TABLE_2_4_PROVIDER,
EPAEndUse,
table_2_4_prices_cents_kwh,
electricity_end_use_retail_prices_cents_kwh,
)

TABLE_8_3_DESCRIPTION = (
Expand Down Expand Up @@ -108,7 +108,7 @@ def table_8_3_purchased_power_gtd_expenses_musd(
'TABLE_8_3_GENERATION_FLOWNAMES',
'TABLE_8_3_PRODUCER',
'TABLE_8_3_SHARED_FLOWNAMES',
'table_2_4_prices_cents_kwh',
'electricity_end_use_retail_prices_cents_kwh',
'table_8_3_gtd_expenses_musd',
'table_8_3_purchased_power_gtd_expenses_musd',
]
4 changes: 2 additions & 2 deletions bedrock/analysis/electricity/d_85/end_use_mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
build_end_use_map,
build_end_use_map_resolved,
classify_industry_end_use,
table_2_4_prices_cents_kwh,
electricity_end_use_retail_prices_cents_kwh,
)
from bedrock.utils.schemas.cornerstone_schemas import ELECTRICITY_DISAGG_SECTORS

Expand All @@ -26,7 +26,7 @@
'build_end_use_map_resolved',
'build_price_tilt_weights_by_column',
'classify_industry_end_use',
'table_2_4_prices_cents_kwh',
'electricity_end_use_retail_prices_cents_kwh',
'write_default_overrides_csv',
]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,9 @@ Indirect fuel-chain emissions remain upstream (fuels assigned to generation in s
After disaggregation, BEA summary sector `"22"` (Utilities) would apply one price index
to all three children. Production applies the standard summary scaling, then a **D7
correction** using UGO305 detail gross-output ratios between `original_year` and
`target_year` per child (`build_electricity_ugo305_scaling_ratios` /
`apply_electricity_d7_scaling_correction_to_A` and `_q` in
`target_year` per child (`build_electricity_detail_GO_growth_ratios` /
`rescale_electricity_children_to_detail_GO_growth_A` /
`rescale_electricity_children_to_detail_GO_growth_q` in
`cornerstone_year_scaling.py`).

For 2017 → 2022, detail GO ratios differentiate G/T/D (generation ~1.62×, transmission
Expand Down Expand Up @@ -287,6 +288,6 @@ Runtime ~1–2 minutes on a typical developer machine.
| 4 | `disaggregate_use_industry_columns`, `_enforce_go_identity_precondition` |
| 5 | `get_electricity_commodity_row_weights`, `disaggregate_use_commodity_rows`, Y split in `cornerstone_disagg_pipeline.py` |
| 6 | `_apply_electricity_disagg_cornerstone_mapping` in `derived.py` |
| 7 | `build_electricity_ugo305_scaling_ratios`, `apply_electricity_d7_scaling_correction_*` in `cornerstone_year_scaling.py` |
| 7 | `build_electricity_detail_GO_growth_ratios`, `rescale_electricity_children_to_detail_GO_growth_*` in `cornerstone_year_scaling.py` |

All in `bedrock/transform/eeio/electricity_disaggregation.py` unless noted.
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
)
from bedrock.transform.eeio.electricity_end_use_mapping import (
build_end_use_map,
table_2_4_prices_cents_kwh,
electricity_end_use_retail_prices_cents_kwh,
)
from bedrock.utils.config.usa_config import reset_usa_config, set_global_usa_config
from bedrock.utils.schemas.cornerstone_schemas import (
Expand Down Expand Up @@ -337,7 +337,9 @@ def analyze() -> dict[str, Any]:
egrid_mwh = float(us_total_net_generation_mwh(model_year))

end_use_map = build_end_use_map()
prices = cast(dict[str, float], table_2_4_prices_cents_kwh(ghg_year))
prices = cast(
dict[str, float], electricity_end_use_retail_prices_cents_kwh(ghg_year)
)
eia = _eia_table_2_2_sales_mwh(model_year)
w_go = build_electricity_disagg_go_weights()
w_trans, w_dist = _td_national_shares()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -753,7 +753,7 @@ def _conversion_factor_detail(config: str) -> dict[str, Any]:
)
from bedrock.transform.eeio.electricity_end_use_mapping import ( # noqa: PLC0415
build_end_use_map,
table_2_4_prices_cents_kwh,
electricity_end_use_retail_prices_cents_kwh,
)

reset_usa_config()
Expand All @@ -764,7 +764,10 @@ def _conversion_factor_detail(config: str) -> dict[str, Any]:
q_usd = float(aq.scaled_q[GENERATION_SECTOR])
mwh = float(us_total_net_generation_mwh(cfg.model_base_year))
c_col = electricity_output_factor(q_usd, mwh)
prices = cast(dict[str, float], table_2_4_prices_cents_kwh(cfg.usa_ghg_data_year))
prices = cast(
dict[str, float],
electricity_end_use_retail_prices_cents_kwh(cfg.usa_ghg_data_year),
)
end_use_map = build_end_use_map()
y_row = _model_year_y_row_221110(aq)
adom_row = cast(pd.Series, aq.Adom.loc[GENERATION_SECTOR])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
from bedrock.transform.eeio.electricity_end_use_mapping import (
EPA_END_USES,
build_end_use_map,
table_2_4_prices_cents_kwh,
electricity_end_use_retail_prices_cents_kwh,
)
from bedrock.utils.schemas.cornerstone_schemas import ELECTRICITY_DISAGG_SECTORS
from bedrock.utils.taxonomy.cornerstone.commodities import COMMODITY_DESC
Expand Down Expand Up @@ -504,7 +504,7 @@ def analyze() -> dict[str, Any]:
eia = _eia_values(int(cfg.model_base_year))
prices = cast(
Mapping[str, float],
table_2_4_prices_cents_kwh(int(cfg.usa_ghg_data_year)),
electricity_end_use_retail_prices_cents_kwh(int(cfg.usa_ghg_data_year)),
)

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
from bedrock.transform.eeio.electricity_end_use_mapping import (
EPA_END_USES,
build_end_use_map,
table_2_4_prices_cents_kwh,
electricity_end_use_retail_prices_cents_kwh,
)
from bedrock.utils.math.formulas import (
backcompute_y_from_A_and_q,
Expand Down Expand Up @@ -232,7 +232,8 @@ def analyze() -> dict[str, Any]:
intermediate_usd, y_row_usd, end_use_map, eia_classes
)
prices_2_4 = cast(
dict[str, float], table_2_4_prices_cents_kwh(int(cfg.usa_ghg_data_year))
dict[str, float],
electricity_end_use_retail_prices_cents_kwh(int(cfg.usa_ghg_data_year)),
)

# Production path (Table 2.4 + eGRID total)
Expand Down
57 changes: 43 additions & 14 deletions bedrock/publish/cache_reset.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@

from __future__ import annotations

import sys
from collections.abc import Callable
from types import ModuleType

from bedrock.extract.iot.io_2017 import (
load_2017_margins_after_redef_usa,
load_2017_margins_before_redef_usa,
)
from bedrock.publish.model_objects import clear_publish_caches
from bedrock.transform.eeio.cornerstone_disagg_pipeline import (
build_end_use_map,
cornerstone_sector_disagg_active,
derive_disagg_io_bundle,
derive_disagg_Ytot_with_trade,
electricity_mixed_units_enabled,
get_waste_disagg_weights,
table_2_4_prices_cents_kwh,
)
from bedrock.transform.eeio.derived import (
derive_Aq_usa,
Expand Down Expand Up @@ -44,12 +44,6 @@
derive_cornerstone_y_nab_mixed_units,
derive_cornerstone_Ytot_matrix_set,
)
from bedrock.transform.eeio.electricity_disaggregation import (
_derive_post_reallocation_checkpoint_for_disagg,
build_electricity_disagg_use_intersection_weights,
build_electricity_ugo305_scaling_ratios,
get_electricity_commodity_row_weights,
)
from bedrock.transform.iot.derive_PRO_to_PUR_ratio import (
derive_margins_cornerstone_usa_at_year,
derive_phi_cornerstone_usa_at_year,
Expand All @@ -61,6 +55,17 @@
get_price_index_ratio,
)

# Cached electricity helpers cleared only if their modules are already loaded.
# Never import electricity_disaggregation / electricity_end_use_mapping here —
# that would re-couple v0.3 / waste-only publish clears.
_ELECTRICITY_DISAGG_CACHED_ATTRS: tuple[str, ...] = (
'get_electricity_commodity_row_weights',
'_derive_post_reallocation_checkpoint_for_disagg',
'build_electricity_disagg_use_intersection_weights',
'build_electricity_detail_GO_growth_ratios',
'build_electricity_disagg_go_weights',
)

UPSTREAM_CACHED_DERIVES: list[Callable[..., object]] = [
derive_B_usa_non_finetuned,
derive_C_usa,
Expand All @@ -70,14 +75,8 @@
cornerstone_sector_disagg_active,
electricity_mixed_units_enabled,
get_waste_disagg_weights,
build_end_use_map,
table_2_4_prices_cents_kwh,
derive_disagg_io_bundle,
derive_disagg_Ytot_with_trade,
get_electricity_commodity_row_weights,
_derive_post_reallocation_checkpoint_for_disagg,
build_electricity_disagg_use_intersection_weights,
build_electricity_ugo305_scaling_ratios,
derive_cornerstone_V,
derive_cornerstone_x,
derive_cornerstone_x_after_redefinition,
Expand Down Expand Up @@ -105,9 +104,39 @@
]


def _clear_cached_attrs(mod: ModuleType, names: tuple[str, ...]) -> None:
for name in names:
fn = getattr(mod, name, None)
cache_clear = getattr(fn, 'cache_clear', None)
if callable(cache_clear):
cache_clear()


def _clear_electricity_caches_if_loaded() -> None:
"""Flush elec ``@cache``s only when those modules are already in ``sys.modules``.

After a flag-on run, leftover caches must still clear when switching to v0.3;
under a never-loaded v0.3 process, this is a no-op and never imports elec.
"""
ed = sys.modules.get('bedrock.transform.eeio.electricity_disaggregation')
if ed is not None:
_clear_cached_attrs(ed, _ELECTRICITY_DISAGG_CACHED_ATTRS)
eum = sys.modules.get('bedrock.transform.eeio.electricity_end_use_mapping')
if eum is not None:
# No @cache today; keep for future-proofing if helpers become cached.
_clear_cached_attrs(
eum,
(
'build_end_use_map',
'electricity_end_use_retail_prices_cents_kwh',
),
)


def clear_all_publish_caches() -> None:
clear_cornerstone_inflation_caches()
for fn in UPSTREAM_CACHED_DERIVES:
if hasattr(fn, 'cache_clear'):
fn.cache_clear()
_clear_electricity_caches_if_loaded()
clear_publish_caches()
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@
_compute_w_row,
_derive_post_reallocation_checkpoint_for_disagg,
_float_ndarray,
_table83_purchased_power_expenses,
_weights_from_table83_expenses,
_iou_utility_gtd_operating_expenses,
_normalize_gtd_expense_weights,
build_electricity_detail_GO_growth_ratios,
build_electricity_disagg_go_weights,
build_electricity_disagg_use_intersection_weights,
build_electricity_ugo305_scaling_ratios,
disaggregate_use_industry_columns,
get_electricity_commodity_row_weights,
)
Expand All @@ -63,7 +63,7 @@
derive_disagg_Ytot_with_trade,
build_electricity_disagg_go_weights,
build_electricity_disagg_use_intersection_weights,
build_electricity_ugo305_scaling_ratios,
build_electricity_detail_GO_growth_ratios,
get_electricity_commodity_row_weights,
_derive_post_reallocation_checkpoint_for_disagg,
derive_cornerstone_V,
Expand Down Expand Up @@ -219,10 +219,10 @@ def test_purchased_power_weights_sum_to_one(self) -> None:
mock_fba_table83_table24,
)

expenses = _table83_purchased_power_expenses(
expenses = _iou_utility_gtd_operating_expenses(
2017, fba=mock_fba_table83_table24()
)
w = _weights_from_table83_expenses(expenses)
w = _normalize_gtd_expense_weights(expenses)
assert set(w.index) == set(ELECTRICITY_DISAGG_SECTORS)
np.testing.assert_allclose(float(w.sum()), 1.0, rtol=1e-9, atol=1e-12)
assert w['221110'] == pytest.approx(49030.0 / (49030.0 + 10804.0 + 4358.0))
Expand Down Expand Up @@ -274,7 +274,7 @@ def test_differentiated_child_q_scaling(
_setup_config(electricity_disagg_config)
try:
aq = derive_cornerstone_Aq_scaled()
ratios = build_electricity_ugo305_scaling_ratios(2017, 2022)
ratios = build_electricity_detail_GO_growth_ratios(2017, 2022)
q_vals = [float(aq.scaled_q[c]) for c in ELECTRICITY_DISAGG_SECTORS]
assert len(set(round(v, 6) for v in q_vals)) == 3
assert ratios['221110'] != pytest.approx(ratios['221121'])
Expand Down
Loading
Loading