Skip to content
Open
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ These flags are grouped into themes:
| Theme | Example flags |
|---|---|
| Schema / taxonomy | `use_cornerstone_2026_model_schema`, `implement_waste_disaggregation`, `implement_electricity_reallocation` |
| Economic IOT (input-output tables) | `use_E_data_year_for_x_in_B`, `iot_before_or_after_redefinition` |
| Economic IOT (input-output tables) | `apply_io_year_adjustments`, `iot_before_or_after_redefinition` |
| GHG attribution | `use_cornerstone_ghg_model` |
| Data vintage | `model_base_year`, `usa_base_io_data_year`, `ipcc_ar_version` |

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@ def test_runtime_B_formula_matches_implementation(self) -> None:

x = (
derive_cornerstone_x_after_redefinition()
if cfg.use_E_data_year_for_x_in_B
if cfg.use_ghg_year_x_in_B
else derive_cornerstone_x()
)
expected = (
Expand Down
8 changes: 4 additions & 4 deletions bedrock/transform/eeio/cornerstone_year_scaling.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def scale_cornerstone_A(
) -> pd.DataFrame:
"""Scale detail A element-wise using summary A ratios.

When ``cfg.adjust_summary_A_and_q_dollar_year`` is set, the target-year summary A
When ``cfg.apply_io_year_adjustments`` is set, the target-year summary A
is rebased into ``original_year`` USD via the ITA-based (industry technology assumption)
summary commodity price ratio before the ratio is derived and taken, so the structural
cross-year ratio is formed in a consistent dollar year.
Expand All @@ -88,7 +88,7 @@ def scale_cornerstone_A(
"""
A_summary_base = _get_summary_A(original_year, dom_or_imp_or_total)
A_summary_target = _get_summary_A(target_year, dom_or_imp_or_total)
if get_usa_config().adjust_summary_A_and_q_dollar_year:
if get_usa_config().apply_io_year_adjustments:
A_summary_target = adjust_summary_A_dollar_year(
A_summary=A_summary_target,
from_year=target_year,
Expand Down Expand Up @@ -157,13 +157,13 @@ def scale_cornerstone_q(
) -> pd.Series[float]:
"""Scale detail q element-wise using summary q ratios.

When ``cfg.adjust_summary_A_and_q_dollar_year`` is set, the target-year summary q
When ``cfg.apply_io_year_adjustments`` is set, the target-year summary q
is rebased into ``original_year`` USD via the ITA-based summary commodity
price ratio before forming the cross-year ratio. Otherwise the ratio is
taken on the raw target-year summary q (pre-realignment behavior).
"""
q_summary_target = derive_summary_q_usa(target_year)
if get_usa_config().adjust_summary_A_and_q_dollar_year:
if get_usa_config().apply_io_year_adjustments:
q_summary_target = adjust_summary_q_dollar_year(
q_summary=q_summary_target,
from_year=target_year,
Expand Down
50 changes: 22 additions & 28 deletions bedrock/transform/eeio/derived_cornerstone.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ def derive_cornerstone_x_after_redefinition(year: int = 0) -> pd.Series[float]:
level as the BEA gross output for *year*, split from 2017 Make structure).

This is the industry ``x`` in ``derive_cornerstone_B_via_vnorm`` when
``use_E_data_year_for_x_in_B`` is True; otherwise that path uses
``use_ghg_year_x_in_B`` (apply_io_year_adjustments) is set; otherwise that path uses
``derive_cornerstone_x()``.
"""
cfg = get_usa_config()
Expand Down Expand Up @@ -502,19 +502,14 @@ def derive_cornerstone_Aq_scaled() -> SingleRegionAqMatrixSet:
if cfg.scale_a_matrix_with_useeio_method:
return base

# CEDA method: our fallback option as of CY26Q2.
# Scale to 2022 (io_year), then inflate to model_base_year.
# However, we are applying some subtle changes to this method:
# 1. scale detail A and q with dollar year adjusted summary numbers
# 2. inflate with commodity pi instead of industry pi
#
# When `cfg.adjust_summary_A_and_q_dollar_year` is set, `scale_cornerstone_A`
# rebases the target-year summary A into 2017 USD before the ratio is taken,
# so the structural cross-year ratio is formed entirely in 2017 USD; the
# scaled detail A is then inflated 2017 → io_year. When the flag is off,
# the ratio carries the raw target-year-vs-2017 price drift and no final
# inflation is applied (pre-realignment behavior).
if cfg.scale_a_matrix_with_ceda_method_as_fallback:
# IO year adjustments (v0.3): CEDA's A approach with dollar-year rebase.
# Scale to usa_io_data_year, then inflate to model_base_year:
# 1. scale detail A and q with dollar-year-adjusted summary numbers
# (`scale_cornerstone_A`/`_q` rebase the target-year summary tables into
# 2017 USD before the ratio is taken, so the structural cross-year ratio
# is formed entirely in 2017 USD),
# 2. inflate with commodity pi instead of industry pi.
if cfg.apply_io_year_adjustments:
Adom = scale_cornerstone_A(
base.Adom,
target_year=io_year,
Expand All @@ -532,16 +527,15 @@ def derive_cornerstone_Aq_scaled() -> SingleRegionAqMatrixSet:
target_year=io_year,
original_year=detail_year,
)
if cfg.adjust_summary_A_and_q_dollar_year:
Adom = inflate_cornerstone_A_matrix_with_commodity_pi(
Adom, original_year=detail_year, target_year=model_year
)
Aimp = inflate_cornerstone_A_matrix_with_commodity_pi(
Aimp, original_year=detail_year, target_year=model_year
)
q = inflate_cornerstone_q_or_y_with_commodity_pi(
q, original_year=detail_year, target_year=model_year
)
Adom = inflate_cornerstone_A_matrix_with_commodity_pi(
Adom, original_year=detail_year, target_year=model_year
)
Aimp = inflate_cornerstone_A_matrix_with_commodity_pi(
Aimp, original_year=detail_year, target_year=model_year
)
q = inflate_cornerstone_q_or_y_with_commodity_pi(
q, original_year=detail_year, target_year=model_year
)
return _cornerstone_aq_matrix_set(Adom=Adom, Aimp=Aimp, scaled_q=q)

Adom = inflate_cornerstone_A_matrix_with_industry_pi(
Expand Down Expand Up @@ -656,12 +650,12 @@ def derive_cornerstone_B_via_vnorm() -> pd.DataFrame:
gross-output time series at ``usa_ghg_data_year`` (nominal), divided by
``PI(usa_ghg_data_year)/PI(usa_detail_original_year)`` so ``E/x`` uses
``usa_detail_original_year`` chain dollars. ``USAConfig`` requires
``use_E_data_year_for_x_in_B`` to be true whenever deflation is on; the
``use_ghg_year_x_in_B`` to be true whenever deflation is on; the
deflate branch always builds nominal ``x`` via
``derive_cornerstone_x_after_redefinition()`` before the PI ratio, so
``use_E_data_year_for_x_in_B`` does not further branch choice here.
``use_ghg_year_x_in_B`` does not further branch choice here.
- otherwise: ``derive_cornerstone_x_after_redefinition()`` when
``use_E_data_year_for_x_in_B`` is True, else ``derive_cornerstone_x()``.
``use_ghg_year_x_in_B`` is True, else ``derive_cornerstone_x()``.
No BEA intermediate or expand_ghg_matrix_from_bea_to_cornerstone.
"""
cfg = get_usa_config()
Expand All @@ -684,7 +678,7 @@ def derive_cornerstone_B_via_vnorm() -> pd.DataFrame:
else:
x = (
derive_cornerstone_x_after_redefinition()
if cfg.use_E_data_year_for_x_in_B
if cfg.use_ghg_year_x_in_B
else derive_cornerstone_x()
)
Vnorm = derive_cornerstone_Vnorm_scrap_corrected()
Expand Down
2 changes: 1 addition & 1 deletion bedrock/utils/config/__tests__/test_usa_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ def test_disallow_m2_without_useeio_schema() -> None:
def test_disallow_deflate_x_without_use_e_for_x_in_b() -> None:
with pytest.raises(
ValueError,
match='deflate_x_to_detail_io_year_for_B requires use_E_data_year_for_x_in_B',
match='deflate_x_to_detail_io_year_for_B requires',
):
USAConfig.model_validate(
{
Expand Down
16 changes: 6 additions & 10 deletions bedrock/utils/config/configs/2025_usa_cornerstone_v0_3.yaml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# FINAL Cornerstone 2025 model — v0.3 release config.
#
# Combines the v0.3 feature set:
# - Update inflation factors -> update_inflation_factors
# - CEDA A approach w/ price adjust -> scale_a_matrix_with_ceda_method_as_fallback
# + adjust_summary_A_and_q_dollar_year
# - Update inflation factors,
# CEDA A approach w/ price adjust,
# GHG-year x in B -> apply_io_year_adjustments
# - Purchaser Price Conversion -> N/A (not part of v0.3)
# - MECS adjustment + UMD GHG data -> use_cornerstone_ghg_model at usa_ghg_data_year=2024
# selects GHG_national_Cornerstone_2024 (the UMD GHGIA 2024
Expand All @@ -29,14 +29,10 @@ use_cornerstone_2026_model_schema: True
# GHG model: Cornerstone GHG FBS (2024 = UMD GHGIA inventory + 2022 MECS attribution).
use_cornerstone_ghg_model: True

# A matrix: CEDA's A approach as fallback, with summary A/q dollar-year price adjustment.
scale_a_matrix_with_ceda_method_as_fallback: True
adjust_summary_A_and_q_dollar_year: True

# Inflation factors.
update_inflation_factors: True
# IO year adjustments: CEDA's A approach with summary dollar-year rebase,
# bedrock-derived inflation factors, and GHG-year x in B.
apply_io_year_adjustments: True

# Shared full-model flags.
use_E_data_year_for_x_in_B: True
implement_waste_disaggregation: True
cornerstone_industry_avg_margins: True
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ usa_ghg_data_year: 2023

use_cornerstone_2026_model_schema: true
use_cornerstone_ghg_model: true
use_E_data_year_for_x_in_B: false
apply_io_year_adjustments: false
implement_waste_disaggregation: false
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ usa_ghg_data_year: 2023

use_cornerstone_2026_model_schema: true
use_cornerstone_ghg_model: true
use_E_data_year_for_x_in_B: false
apply_io_year_adjustments: false
implement_waste_disaggregation: true
5 changes: 1 addition & 4 deletions bedrock/utils/config/configs/v03_waterfall_final.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@ use_cornerstone_2026_model_schema: true

use_cornerstone_ghg_model: true

scale_a_matrix_with_ceda_method_as_fallback: true
adjust_summary_A_and_q_dollar_year: true
update_inflation_factors: true

use_E_data_year_for_x_in_B: true
apply_io_year_adjustments: true
implement_waste_disaggregation: true
5 changes: 1 addition & 4 deletions bedrock/utils/config/configs/v03_waterfall_g2_methods.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,9 @@ usa_ghg_data_year: 2023

use_cornerstone_2026_model_schema: true
use_cornerstone_ghg_model: true
use_E_data_year_for_x_in_B: true
apply_io_year_adjustments: true
implement_waste_disaggregation: true

scale_a_matrix_with_useeio_method: false
useeio_margins: false
cornerstone_industry_avg_margins: true
scale_a_matrix_with_ceda_method_as_fallback: true
adjust_summary_A_and_q_dollar_year: true
update_inflation_factors: true
5 changes: 1 addition & 4 deletions bedrock/utils/config/configs/v03_waterfall_g3_data.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@ usa_ghg_data_year: 2024

use_cornerstone_2026_model_schema: true
use_cornerstone_ghg_model: true
use_E_data_year_for_x_in_B: true
apply_io_year_adjustments: true
implement_waste_disaggregation: true

scale_a_matrix_with_ceda_method_as_fallback: true
adjust_summary_A_and_q_dollar_year: true
update_inflation_factors: true
cornerstone_industry_avg_margins: true
26 changes: 15 additions & 11 deletions bedrock/utils/config/usa_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,17 @@ class USAConfig(BaseModel):
use_cornerstone_2026_model_schema: bool = False # DRI: mo.li
use_useeio_schema: bool = False
### IO Methodology selection
# "IO year adjustments" bucket: CEDA A/q scaling to usa_io_data_year with
# summary dollar-year rebase, bedrock-derived industry inflation factors,
# and gross output at usa_ghg_data_year as B's denominator x.
apply_io_year_adjustments: bool = False
use_E_data_year_for_x_in_B: bool = Field(
default=False,
description=(
'Use an x corresponding to usa_ghg_data_year'
'in B. Must be true whenever deflate_x_to_detail_io_year_for_B is true.'
'Deprecated USEEIO-parity compatibility flag: GHG-year x in B '
'without the rest of the IO-year adjustments. Superseded by '
'apply_io_year_adjustments; kept for configs on the pre-v0.3 A '
'footing until the USEEIO-recreation removal.'
),
)
deflate_x_to_detail_io_year_for_B: bool = Field(
Expand All @@ -84,9 +90,7 @@ class USAConfig(BaseModel):
implement_electricity_reallocation: bool = False # DRI: jorge.vendries
implement_electricity_disaggregation: bool = False # DRI: jorge.vendries
implement_electricity_mixed_units: bool = False # DRI: jorge.vendries
scale_a_matrix_with_ceda_method_as_fallback: bool = False # DRI: mo.li
scale_a_matrix_with_useeio_method: bool = False # DRI: mo.li
adjust_summary_A_and_q_dollar_year: bool = False # DRI: mo.li
ceda_margins: bool = False # DRI: WesIngwersen
useeio_margins: bool = False # DRI: WesIngwersen
cornerstone_industry_avg_margins: bool = False # DRI: WesIngwersen
Expand All @@ -95,8 +99,6 @@ class USAConfig(BaseModel):
# usa_ghg_data_year) vs the legacy CEDA-methodology FBS (2023 only).
use_cornerstone_ghg_model: bool = False
use_ghg_national_2023_m2: bool = False
### Inflation factors
update_inflation_factors: bool = False

#####
# Diagnostics baseline (parquet snapshots vs USEEIO Excel on GCS)
Expand Down Expand Up @@ -147,13 +149,10 @@ def _validate_diagnostics_baseline(self) -> USAConfig:

@model_validator(mode='after')
def _validate_deflate_x_requires_use_e_for_x_in_b(self) -> USAConfig:
if (
self.deflate_x_to_detail_io_year_for_B
and not self.use_E_data_year_for_x_in_B
):
if self.deflate_x_to_detail_io_year_for_B and not self.use_ghg_year_x_in_B:
raise ValueError(
'deflate_x_to_detail_io_year_for_B requires use_E_data_year_for_x_in_B '
'to be true'
'or apply_io_year_adjustments to be true'
)
return self

Expand Down Expand Up @@ -234,6 +233,11 @@ def _validate_ghg_flag_compatibility(self) -> USAConfig:
def usa_detail_original_year(self) -> ta.Literal[2012, 2017]:
return 2017

@property
def use_ghg_year_x_in_B(self) -> bool:
"""B's denominator x is gross output at ``usa_ghg_data_year``."""
return self.apply_io_year_adjustments or self.use_E_data_year_for_x_in_B

def to_dict(self) -> dict[str, object]:
"""Return a JSON-serializable dictionary representation of the config.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ def test_v_inflation_uses_industry_row_axis(
"""
# apply_inflation=True is the new BEA-derived industry-PI path; pin the
# flag so the price ratio is industry-indexed (matching V's industry
# rows). Under update_inflation_factors=False the helper returns
# rows). Under apply_io_year_adjustments=False the helper returns
# commodity-indexed values for the legacy A-matrix flow.
monkeypatch.setattr(get_usa_config(), 'update_inflation_factors', True)
monkeypatch.setattr(get_usa_config(), 'apply_io_year_adjustments', True)

Vnorm_True = derive_cornerstone_Vnorm_scrap_corrected(
apply_inflation=True, target_year=2024
Expand Down
8 changes: 4 additions & 4 deletions bedrock/utils/economic/inflation_helpers_cornerstone.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,13 @@ def _industry_price_index_levels() -> pd.DataFrame:
"""Wide sector × year PI levels for cornerstone industry-ratio math.

``useeio_margins``: USEEIOR v1.8.0 ``Detail_CPI_IO_17sch`` (GCS snapshot).
``update_inflation_factors``: bedrock-derived industry PI.
``apply_io_year_adjustments``: bedrock-derived industry PI.
Otherwise: bedrock BEA parquet (``BEA_PriceIndex``).
"""
cfg = get_usa_config()
if cfg.useeio_margins:
return obtain_useeior_detail_industry_cpi_levels()
if cfg.update_inflation_factors:
if cfg.apply_io_year_adjustments:
return derive_industry_price_index()
return obtain_inflation_factors_from_reference_data()

Expand All @@ -106,7 +106,7 @@ def get_cornerstone_industry_price_ratio(
"""
cfg = get_usa_config()
price_index = _industry_price_index_levels()
if cfg.update_inflation_factors:
if cfg.apply_io_year_adjustments:
target_codes = CORNERSTONE_INDUSTRIES
else:
# Reindex to commodities so downstream `diag(p) @ A @ diag(1/p)`
Expand Down Expand Up @@ -648,7 +648,7 @@ def _cornerstone_indexed_industry_pi(year: int) -> pd.Series[float]:
``get_cornerstone_industry_price_ratio``).

Always indexed on ``CORNERSTONE_INDUSTRIES`` regardless of
``update_inflation_factors`` (V_norm.T @ pi_industry in the ITA flow needs
``apply_io_year_adjustments`` (V_norm.T @ pi_industry in the ITA flow needs
industry granularity; the existing dispatch's commodity branch returns
commodity-indexed values for the legacy ``diag(p) @ A @ diag(1/p)`` flow,
which we don't want here).
Expand Down
2 changes: 1 addition & 1 deletion bedrock/utils/economic/inflation_helpers_useeio.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
from bedrock.utils.io.gcp_paths import gcs_extract_input_path
from bedrock.utils.io.local_extract_input_data import local_extract_input_dir

# Distinct from ``BEA_PriceIndex`` (bedrock parquet) and ``update_inflation_factors``.
# Distinct from ``BEA_PriceIndex`` (bedrock parquet) and ``apply_io_year_adjustments``.
USEEIOR_INDUSTRY_CPI_GCS_SOURCE = 'USEEIOR_v180_IndustryCPI'
USEEIOR_DETAIL_CPI_IO_17SCH_FILENAME = 'useeior_v1.8.0_Detail_CPI_IO_17sch.csv'
USEEIOR_DETAIL_CPI_IO_17SCH_GCS_PATH = gcs_extract_input_path(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def mock_load(name: str) -> pd.DataFrame:

mock_config = MagicMock()
mock_config.use_cornerstone_2026_model_schema = False
mock_config.use_E_data_year_for_x_in_B = False
mock_config.use_ghg_year_x_in_B = False
mock_config.diagnostics_baseline_source = "gcs_snapshot"

with (
Expand Down
2 changes: 1 addition & 1 deletion bedrock/utils/validation/calculate_ef_diagnostics.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ def calculate_ef_diagnostics(sheet_id: str) -> None:
logger.info('Skipping mixed_vs_monetary_221110 (mixed-units gate off)')

# Effective x decomposition (Cornerstone method only)
if config.use_E_data_year_for_x_in_B:
if config.use_ghg_year_x_in_B:
from bedrock.utils.validation.diagnostics_helpers import (
compute_effective_x_comparison,
)
Expand Down
2 changes: 1 addition & 1 deletion bedrock/utils/validation/diagnostics_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ def d_n_new_inflated_eligibility(cfg: USAConfig) -> tuple[bool, str]:
'EF denominator adjustment for D/N is identity (no separate inflated columns)',
)
return (True, '')
if cfg.use_E_data_year_for_x_in_B:
if cfg.use_ghg_year_x_in_B:
return (
False,
'use_E_data_year_for_x_in_B without deflate_x_to_detail_io_year_for_B: '
Expand Down
Loading