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 .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ data/isone/capacity/ara/parquet/
data/isone/capacity/fca/parquet/
data/isone/lmp/parquet/
data/isone/hourly_demand/zones/
data/isone/hourly_demand/utilities/
data/isone/ancillary/parquet/
data/nyiso/icap/parquet/
data/nyiso/lbmp/zips/
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ After individual CAIRO runs complete, post-processing scripts consolidate result
| **`rate_design/`** | Package root. Heat pump rate design lives under `rate_design/hp_rates/`. |
| **`rate_design/hp_rates/`** | Shared scenario entrypoint (`run_scenario.py`), shared **Justfile** (primary task interface for all states). State-specific thin Justfiles and `config/` dirs live under `rate_design/hp_rates/{ny,ri}/`. |
| **`rate_design/hp_rates/{ny,ri}/`** | State-specific thin Justfile (imports shared), `state.env`, and `config/` (tariffs JSON in tariffs/electric and tariffs/gas, tariff_maps CSV in tariff_maps/electric and tariff_maps/gas, marginal_costs). Large artifacts (buildstock raw/processed, cairo_cases) are git-ignored; sync via S3 or keep local. |
| **`data/eia/hourly_loads/`** | EIA zone load fetch and utility load aggregation; eia_region_config (state/utility config, get_aws_storage_options); Justfile for fetch-zone-data and aggregate-utility-loads. |
| **`data/eia/hourly_loads/`** | EIA zone load fetch and utility load aggregation; eia_region_config (state/utility config); Justfile for fetch-zone-data and aggregate-utility-loads. |
| **`data/eia/861/`** | EIA-861 utility stats (PUDL yearly sales); fetch_electric_utility_stat_parquets.py; Justfile build-utility-stats (local parquet), update (upload to s3://data.sb/eia/861/electric_utility_stats/), fetch-utility-stats STATE (CSV to stdout). |
| **`data/fred/cpi/`** | FRED CPI series; Justfile fetch-cpi (local parquet/), upload (sync to s3://data.sb/fred/cpi/). |
| **`data/aspe/fpl/`** | ASPE Federal Poverty Guidelines fetch; Justfile fetch. Output: utils/post/data/fpl_guidelines.yaml (used by LMI discount logic). |
Expand Down
4 changes: 2 additions & 2 deletions context/code/cairo/cairo_elastic_cluster.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ With a **Dask Distributed** cluster, the driver and scheduler run on one node; w
- **Overhead:** You must deploy workers (e.g. EC2 or Batch) that have the same mount. With Fargate or generic Batch workers, that can be fiddly (custom AMI or entrypoint that mounts S3).

- **B. S3 URIs + storage_options (no shared mount)**\
Pass **S3 URIs** (e.g. `s3://data.sb/nrel/resstock/...`) and **storage_options** (e.g. `{"region_name": "us-west-2"}` or from `get_aws_storage_options()`) through the stack so that workers can call `pd.read_parquet(s3_uri, storage_options=...)` and read directly from S3.
Pass **S3 URIs** (e.g. `s3://data.sb/nrel/resstock/...`) and **storage_options** (e.g. `{"region_name": "us-west-2"}` or from `utils.file_io.get_aws_storage_options()`) through the stack so that workers can call `pd.read_parquet(s3_uri, storage_options=...)` and read directly from S3.
- **Overhead:** Requires code changes in both codebases (see below). No need for a shared mount; any worker with AWS credentials and network can read.

Option **B** is more portable (works with Fargate, Batch, any node with S3 access) and is the one that forces the concrete changes below. Option A is “no code change” but constrains how you run workers.
Expand Down Expand Up @@ -92,7 +92,7 @@ CAIRO does **not** need to know about “the cluster”; it only needs to be abl
2. **Pass storage_options into CAIRO**
- Where the platform calls CAIRO (e.g. `_return_load`, `return_buildingstock`, and the top-level `simulate()` or helpers that take paths), it must pass `storage_options` when the paths are S3. That implies:
- CAIRO’s public API (e.g. `MeetRevenueSufficiencySystemWide`, `simulate()`, or the load/buildingstock functions) must accept an optional `storage_options` (or a “run config” that includes it) and pass it through to all parquet-reading code.
- The platform already has `get_aws_storage_options()` (e.g. in `data.eia.hourly_loads.eia_region_config` or similar). When running in “cluster mode” with S3 URIs, the platform should pass that (or equivalent) into CAIRO.
- The platform already has `get_aws_storage_options()` (in `utils.file_io`). When running in “cluster mode” with S3 URIs, the platform should pass that (or equivalent) into CAIRO.

3. **Use Dask Distributed instead of the process scheduler**
- Instead of `dask.config.set(scheduler="processes", num_workers=...)`, the platform (or a cluster launcher script) would create a `distributed.Client` connected to a Dask scheduler (e.g. one started by dask-cloudprovider), and either:
Expand Down
12 changes: 0 additions & 12 deletions data/eia/hourly_loads/eia_region_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
- utility service areas used by utility aggregation scripts
"""

import os
from dataclasses import dataclass
from typing import TypedDict

Expand Down Expand Up @@ -139,14 +138,3 @@ def get_utility_zone_mapping_for_state(state: str) -> dict[str, list[str]]:
break

return utility_zone_mapping


def get_aws_storage_options() -> dict[str, str]:
"""Return Polars-compatible AWS storage options for S3 access."""
aws_region = (
os.getenv("AWS_DEFAULT_REGION") or os.getenv("AWS_REGION") or "us-west-2"
)
return {
"region": aws_region,
"default_region": aws_region,
}
2 changes: 1 addition & 1 deletion utils/cairo.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from cairo.rates_tool.loads import __timeshift__
from cloudpathlib import S3Path

from data.eia.hourly_loads.eia_region_config import get_aws_storage_options
from utils.file_io import get_aws_storage_options
from utils.types import ElectricUtility

CambiumPathLike = str | Path | S3Path
Expand Down
2 changes: 1 addition & 1 deletion utils/data_prep/marginal_costs/generate_bulk_tx_mc.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@

from dotenv import load_dotenv

from data.eia.hourly_loads.eia_region_config import get_aws_storage_options
from utils.file_io import get_aws_storage_options
from utils.data_prep.marginal_costs.bulk_tx_isone import (
AESC_2024_AVOIDED_PTF_KW_YEAR,
DEFAULT_N_PEAK_HOURS,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ def main() -> None:
)

load_dotenv()
from data.eia.hourly_loads.eia_region_config import get_aws_storage_options
from utils.file_io import get_aws_storage_options

storage_options = get_aws_storage_options()

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

from dotenv import load_dotenv

from data.eia.hourly_loads.eia_region_config import get_aws_storage_options
from utils.file_io import get_aws_storage_options
from utils.data_prep.marginal_costs.supply_capacity_nyiso import (
N_PEAK_HOURS_PER_MONTH,
compute_supply_capacity_mc,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from dotenv import load_dotenv

from data.eia.hourly_loads.eia_region_config import get_aws_storage_options
from utils.file_io import get_aws_storage_options
from utils.data_prep.marginal_costs.supply_energy import (
compute_isone_supply_energy_mc,
compute_pjm_supply_energy_mc,
Expand Down
6 changes: 2 additions & 4 deletions utils/data_prep/marginal_costs/generate_utility_tx_dx_mc.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,8 @@
from cloudpathlib import S3Path
from dotenv import load_dotenv

from data.eia.hourly_loads.eia_region_config import (
get_aws_storage_options,
get_state_config,
)
from data.eia.hourly_loads.eia_region_config import get_state_config
from utils.file_io import get_aws_storage_options
from utils.data_prep.marginal_costs.supply_utils import (
warn_if_multiple_partition_parquets,
)
Expand Down
12 changes: 12 additions & 0 deletions utils/file_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,25 @@

import io
import itertools
import os
from pathlib import Path
from typing import Any

import boto3
import polars as pl


def get_aws_storage_options() -> dict[str, str]:
"""Return Polars-compatible AWS storage options for S3 access."""
aws_region = (
os.getenv("AWS_DEFAULT_REGION") or os.getenv("AWS_REGION") or "us-west-2"
)
return {
"region": aws_region,
"default_region": aws_region,
}


def read_csv_from_s3(s3_path: str, **kwargs: Any) -> pl.DataFrame:
"""Read a CSV file from S3 into a Polars DataFrame.

Expand Down
2 changes: 1 addition & 1 deletion utils/mid/compute_fair_default_inputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from cloudpathlib import S3Path
from dotenv import load_dotenv

from data.eia.hourly_loads.eia_region_config import get_aws_storage_options
from utils.file_io import get_aws_storage_options
from utils.loads import ELECTRIC_LOAD_COL, ELECTRIC_PV_COL, grid_consumption_expr
from utils.loads import scan_resstock_loads, scan_resstock_loads_monthly
from utils.mid.compute_subclass_rr import (
Expand Down
2 changes: 1 addition & 1 deletion utils/mid/compute_flat_discount_inputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from cloudpathlib import S3Path
from dotenv import load_dotenv

from data.eia.hourly_loads.eia_region_config import get_aws_storage_options
from utils.file_io import get_aws_storage_options
from utils.mid.compute_subclass_rr import (
BAT_METRIC_CHOICES,
DEFAULT_BAT_METRIC,
Expand Down
2 changes: 1 addition & 1 deletion utils/mid/compute_seasonal_discount_inputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from cloudpathlib import S3Path
from dotenv import load_dotenv

from data.eia.hourly_loads.eia_region_config import get_aws_storage_options
from utils.file_io import get_aws_storage_options
from utils.mid.compute_subclass_rr import (
DEFAULT_BAT_METRIC,
DEFAULT_GROUP_COL,
Expand Down
2 changes: 1 addition & 1 deletion utils/mid/compute_subclass_rr.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from cloudpathlib import S3Path
from dotenv import load_dotenv

from data.eia.hourly_loads.eia_region_config import get_aws_storage_options
from utils.file_io import get_aws_storage_options
from utils.loads import ELECTRIC_PV_COL, grid_consumption_expr, scan_resstock_loads
from utils.pre.season_config import (
DEFAULT_SEASONAL_DISCOUNT_WINTER_MONTHS,
Expand Down
2 changes: 1 addition & 1 deletion utils/mid/prepare_fair_default_tariffs.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from cloudpathlib import S3Path
from dotenv import load_dotenv

from data.eia.hourly_loads.eia_region_config import get_aws_storage_options
from utils.file_io import get_aws_storage_options
from utils import get_aws_region
from utils.cairo import (
add_bulk_tx_and_dist_and_sub_tx_marginal_cost,
Expand Down
2 changes: 1 addition & 1 deletion utils/post/apply_ny_lmi_discounts_to_cairo_bills.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
from cloudpathlib import S3Path
from dotenv import load_dotenv

from data.eia.hourly_loads.eia_region_config import get_aws_storage_options
from utils.file_io import get_aws_storage_options
from utils.post.lmi_common import (
assign_ny_tier_expr,
fpl_pct_expr,
Expand Down
2 changes: 1 addition & 1 deletion utils/post/apply_ny_lmi_to_master_bills.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
import polars as pl
from dotenv import load_dotenv

from data.eia.hourly_loads.eia_region_config import get_aws_storage_options
from utils.file_io import get_aws_storage_options
from utils.post.lmi_common import (
assign_ny_tier_expr,
fpl_pct_expr,
Expand Down
2 changes: 1 addition & 1 deletion utils/post/apply_ri_lmi_discounts_to_bills.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
from cloudpathlib import S3Path
from dotenv import load_dotenv

from data.eia.hourly_loads.eia_region_config import get_aws_storage_options
from utils.file_io import get_aws_storage_options
from utils.post.lmi_common import (
assign_ri_gas_tier_expr,
assign_ri_tier_expr,
Expand Down
2 changes: 1 addition & 1 deletion utils/post/build_master_bat.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@

import polars as pl

from data.eia.hourly_loads.eia_region_config import get_aws_storage_options
from utils.file_io import get_aws_storage_options
from utils.post.io import BLDG_ID, scan
from utils.post.master_run12_passthrough import (
REFERENCE_COMB_RUN_PAIR,
Expand Down
2 changes: 1 addition & 1 deletion utils/post/build_master_bills.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@

import polars as pl

from data.eia.hourly_loads.eia_region_config import get_aws_storage_options
from utils.file_io import get_aws_storage_options
from utils.post import apply_ny_lmi_to_master_bills as ny_lmi_master_bills
from utils.post.apply_ny_lmi_to_master_bills import apply_ny_lmi_to_master
from utils.post.apply_ri_lmi_discounts_to_bills import apply_ri_lmi_to_master
Expand Down
2 changes: 1 addition & 1 deletion utils/post/compare_master_batches.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
import numpy as np
import polars as pl

from data.eia.hourly_loads.eia_region_config import get_aws_storage_options
from utils.file_io import get_aws_storage_options
from utils.post.build_master_bat import VALID_RUN_PAIRS
from utils.post.io import BLDG_ID, path_or_s3

Expand Down
2 changes: 1 addition & 1 deletion utils/post/validate_lmi_electric_discounts.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
import polars as pl
from dotenv import load_dotenv

from data.eia.hourly_loads.eia_region_config import get_aws_storage_options
from utils.file_io import get_aws_storage_options
from utils.post.lmi_common import get_ny_eap_credits_df

matplotlib.use("Agg")
Expand Down
2 changes: 1 addition & 1 deletion utils/post/validate_lmi_gas_discounts.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import polars as pl
from dotenv import load_dotenv

from data.eia.hourly_loads.eia_region_config import get_aws_storage_options
from utils.file_io import get_aws_storage_options
from utils.post.lmi_common import get_ny_eap_credits_df

matplotlib.use("Agg")
Expand Down
2 changes: 1 addition & 1 deletion utils/post/validate_ny_mc_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
)
from plotnine.composition import Compose

from data.eia.hourly_loads.eia_region_config import get_aws_storage_options
from utils.file_io import get_aws_storage_options
from utils.data_prep.marginal_costs.supply_utils import (
build_mc_partition_parquet_path,
build_mc_partition_path,
Expand Down
2 changes: 1 addition & 1 deletion utils/post/validate_passthrough_rr_master_vs_yaml.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import polars as pl
import yaml

from data.eia.hourly_loads.eia_region_config import get_aws_storage_options
from utils.file_io import get_aws_storage_options
from utils import get_project_root
from utils.mid.compute_subclass_rr import parse_group_value_to_subclass
from utils.mid.resolve_subclass_config import resolve_subclass_config
Expand Down
2 changes: 1 addition & 1 deletion utils/pre/calibrate_demand_flex_elasticity.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
import polars as pl
import yaml

from data.eia.hourly_loads.eia_region_config import get_aws_storage_options
from utils.file_io import get_aws_storage_options
from utils.cairo import (
_build_period_consumption,
_build_period_shift_targets,
Expand Down
2 changes: 1 addition & 1 deletion utils/pre/create_flat_tariffs.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def _s3_storage_options(path: str) -> dict[str, str] | None:
if not path.startswith("s3://"):
return None
try:
from data.eia.hourly_loads.eia_region_config import get_aws_storage_options
from utils.file_io import get_aws_storage_options

return get_aws_storage_options()
except ImportError:
Expand Down
2 changes: 1 addition & 1 deletion utils/pre/rev_requirement/analyze_rr_scatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
theme_minimal,
)

from data.eia.hourly_loads.eia_region_config import get_aws_storage_options
from utils.file_io import get_aws_storage_options
from utils.scenario_config import get_residential_customer_count_from_utility_stats

UtilityData = dict[str, str | float]
Expand Down
2 changes: 1 addition & 1 deletion utils/pre/rev_requirement/compute_rr.py
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ def main() -> None:
storage_options = None
if args.path_electric_utility_stats.startswith("s3://"):
try:
from data.eia.hourly_loads.eia_region_config import get_aws_storage_options
from utils.file_io import get_aws_storage_options

storage_options = get_aws_storage_options()
except ImportError:
Expand Down
4 changes: 1 addition & 3 deletions utils/pre/rev_requirement/estimate_psegli_rr.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,9 +273,7 @@ def main() -> None:
storage_options = None
if args.path_electric_utility_stats.startswith("s3://"):
try:
from data.eia.hourly_loads.eia_region_config import (
get_aws_storage_options,
)
from utils.file_io import get_aws_storage_options

storage_options = get_aws_storage_options()
except ImportError:
Expand Down
2 changes: 1 addition & 1 deletion utils/pre/write_tariff_maps_from_scenario.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import polars as pl
import yaml

from data.eia.hourly_loads.eia_region_config import get_aws_storage_options
from utils.file_io import get_aws_storage_options
from utils.pre.electric_tariff_mapper import generate_tariff_map_from_scenario_keys

_S3_OPTS = get_aws_storage_options()
Expand Down