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
220 changes: 220 additions & 0 deletions codecarbon/data/private_infra/2023/usa_emissions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
{
"_unit": {
"emissions": "lbs/MWh",
"regionCode": "2 digit state/region code"
},
"_source": {
"name": "EPA eGRID2023, annual CO2 equivalent total output emission rate",
"url": "https://www.epa.gov/egrid/download-data",
"field": "STC2ERTA",
"year": 2023
},
"alabama": {
"emissions": 713.976,
"regionCode": "AL"
},
"alaska": {
"emissions": 814.457,
"regionCode": "AK"
},
"arizona": {
"emissions": 689.104,
"regionCode": "AZ"
},
"arkansas": {
"emissions": 998.414,
"regionCode": "AR"
},
"california": {
"emissions": 394.769,
"regionCode": "CA"
},
"colorado": {
"emissions": 1091.078,
"regionCode": "CO"
},
"connecticut": {
"emissions": 540.674,
"regionCode": "CT"
},
"delaware": {
"emissions": 704.171,
"regionCode": "DE"
},
"district of columbia": {
"emissions": 395.011,
"regionCode": "DC"
},
"florida": {
"emissions": 789.133,
"regionCode": "FL"
},
"georgia": {
"emissions": 717.445,
"regionCode": "GA"
},
"hawaii": {
"emissions": 1394.68,
"regionCode": "HI"
},
"idaho": {
"emissions": 313.88,
"regionCode": "ID"
},
"illinois": {
"emissions": 474.436,
"regionCode": "IL"
},
"indiana": {
"emissions": 1465.502,
"regionCode": "IN"
},
"iowa": {
"emissions": 634.156,
"regionCode": "IA"
},
"kansas": {
"emissions": 733.284,
"regionCode": "KS"
},
"kentucky": {
"emissions": 1747.004,
"regionCode": "KY"
},
"louisiana": {
"emissions": 763.068,
"regionCode": "LA"
},
"maine": {
"emissions": 316.835,
"regionCode": "ME"
},
"maryland": {
"emissions": 522.207,
"regionCode": "MD"
},
"massachusetts": {
"emissions": 830.101,
"regionCode": "MA"
},
"michigan": {
"emissions": 797.432,
"regionCode": "MI"
},
"minnesota": {
"emissions": 752.329,
"regionCode": "MN"
},
"mississippi": {
"emissions": 828.274,
"regionCode": "MS"
},
"missouri": {
"emissions": 1454.593,
"regionCode": "MO"
},
"montana": {
"emissions": 1063.921,
"regionCode": "MT"
},
"nebraska": {
"emissions": 1025.822,
"regionCode": "NE"
},
"nevada": {
"emissions": 643.859,
"regionCode": "NV"
},
"new hampshire": {
"emissions": 276.222,
"regionCode": "NH"
},
"new jersey": {
"emissions": 470.168,
"regionCode": "NJ"
},
"new mexico": {
"emissions": 773.637,
"regionCode": "NM"
},
"new york": {
"emissions": 466.616,
"regionCode": "NY"
},
"north carolina": {
"emissions": 626.438,
"regionCode": "NC"
},
"north dakota": {
"emissions": 1297.852,
"regionCode": "ND"
},
"ohio": {
"emissions": 1068.27,
"regionCode": "OH"
},
"oklahoma": {
"emissions": 648.834,
"regionCode": "OK"
},
"oregon": {
"emissions": 364.963,
"regionCode": "OR"
},
"pennsylvania": {
"emissions": 647.871,
"regionCode": "PA"
},
"rhode island": {
"emissions": 840.004,
"regionCode": "RI"
},
"south carolina": {
"emissions": 560.363,
"regionCode": "SC"
},
"south dakota": {
"emissions": 335.582,
"regionCode": "SD"
},
"tennessee": {
"emissions": 661.166,
"regionCode": "TN"
},
"texas": {
"emissions": 771.179,
"regionCode": "TX"
},
"utah": {
"emissions": 1421.234,
"regionCode": "UT"
},
"vermont": {
"emissions": 52.239,
"regionCode": "VT"
},
"virginia": {
"emissions": 539.599,
"regionCode": "VA"
},
"washington": {
"emissions": 266.585,
"regionCode": "WA"
},
"west virginia": {
"emissions": 1968.869,
"regionCode": "WV"
},
"wisconsin": {
"emissions": 1163.572,
"regionCode": "WI"
},
"wyoming": {
"emissions": 1833.263,
"regionCode": "WY"
},
"usa": {
"emissions": 770.884,
"regionCode": "usa"
}
}
145 changes: 145 additions & 0 deletions codecarbon/data/private_infra/update_usa_emissions.py
Comment thread
ArshiaBajaj marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
#!/usr/bin/env python3
"""Build ``usa_emissions.json`` from the EPA eGRID data workbook.

Download the workbook from https://www.epa.gov/egrid/download-data, then run:

uv run --with openpyxl python codecarbon/data/private_infra/update_usa_emissions.py \\
egrid2023_data_rev2.xlsx --year 2023

The state rates come from the ``ST<yy>`` sheet and the national rate from the
``US<yy>`` sheet. Both sheets have a description row, then a row of eGRID
field names, then the data.
"""

from __future__ import annotations

import argparse
import json
from pathlib import Path

import pandas as pd

STATE_NAMES = {
"AK": "alaska",
"AL": "alabama",
"AR": "arkansas",
"AZ": "arizona",
"CA": "california",
"CO": "colorado",
"CT": "connecticut",
"DC": "district of columbia",
"DE": "delaware",
"FL": "florida",
"GA": "georgia",
"HI": "hawaii",
"IA": "iowa",
"ID": "idaho",
"IL": "illinois",
"IN": "indiana",
"KS": "kansas",
"KY": "kentucky",
"LA": "louisiana",
"MA": "massachusetts",
"MD": "maryland",
"ME": "maine",
"MI": "michigan",
"MN": "minnesota",
"MO": "missouri",
"MS": "mississippi",
"MT": "montana",
"NC": "north carolina",
"ND": "north dakota",
"NE": "nebraska",
"NH": "new hampshire",
"NJ": "new jersey",
"NM": "new mexico",
"NV": "nevada",
"NY": "new york",
"OH": "ohio",
"OK": "oklahoma",
"OR": "oregon",
"PA": "pennsylvania",
"RI": "rhode island",
"SC": "south carolina",
"SD": "south dakota",
"TN": "tennessee",
"TX": "texas",
"UT": "utah",
"VA": "virginia",
"VT": "vermont",
"WA": "washington",
"WI": "wisconsin",
"WV": "west virginia",
"WY": "wyoming",
}

RATE_FIELDS = {
"co2e": ("C2ERTA", "CO2 equivalent"),
"co2": ("CO2RTA", "CO2"),
}


def read_egrid_rates(workbook: Path, year: int, gas: str = "co2e") -> tuple:
"""Return the state rates and the national rate (lb/MWh) for one gas."""
yy = f"{year % 100:02d}"
field = RATE_FIELDS[gas][0]
states = pd.read_excel(workbook, sheet_name=f"ST{yy}", header=1)
national = pd.read_excel(workbook, sheet_name=f"US{yy}", header=1)
state_rates = dict(zip(states["PSTATABB"], states[f"ST{field}"]))
return state_rates, float(national[f"US{field}"].iloc[0])


def build_usa_emissions(
state_rates: dict, national_rate: float, year: int, gas: str = "co2e"
) -> dict:
field, gas_label = RATE_FIELDS[gas]
missing = sorted(set(STATE_NAMES) - set(state_rates))
if missing:
raise ValueError(f"States missing from eGRID{year}: {', '.join(missing)}")

data = {
"_unit": {
"emissions": "lbs/MWh",
Comment thread
ArshiaBajaj marked this conversation as resolved.
"regionCode": "2 digit state/region code",
},
"_source": {
"name": f"EPA eGRID{year}, annual {gas_label} total output emission rate",
"url": "https://www.epa.gov/egrid/download-data",
"field": f"ST{field}",
"year": year,
},
}
for code, name in sorted(STATE_NAMES.items(), key=lambda item: item[1]):
data[name] = {
"emissions": round(float(state_rates[code]), 3),
"regionCode": code,
}
data["usa"] = {"emissions": round(national_rate, 3), "regionCode": "usa"}
return data


def main() -> None:
parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
parser.add_argument("workbook", type=Path, help="eGRID data workbook (.xlsx)")
parser.add_argument("--year", type=int, required=True, help="eGRID data year")
parser.add_argument("--gas", choices=sorted(RATE_FIELDS), default="co2e")
parser.add_argument(
"--output",
type=Path,
default=None,
help="defaults to <year>/usa_emissions.json next to this script",
)
args = parser.parse_args()

output = args.output or (
Path(__file__).resolve().parent / str(args.year) / "usa_emissions.json"
)
state_rates, national_rate = read_egrid_rates(args.workbook, args.year, args.gas)
data = build_usa_emissions(state_rates, national_rate, args.year, args.gas)
output.parent.mkdir(parents=True, exist_ok=True)
output.write_text(json.dumps(data, indent=2) + "\n")
print(f"Wrote {len(STATE_NAMES)} states and the national rate to {output}")


if __name__ == "__main__":
main()
2 changes: 1 addition & 1 deletion codecarbon/input.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def __init__(self):
self.config = {
"geo_js_url": "https://get.geojs.io/v1/ip/geo.json",
"cloud_emissions_path": "data/cloud/impact.csv",
"usa_emissions_data_path": "data/private_infra/2016/usa_emissions.json",
"usa_emissions_data_path": "data/private_infra/2023/usa_emissions.json",
"can_energy_mix_data_path": "data/private_infra/2023/canada_energy_mix.json", # noqa: E501
"global_energy_mix_data_path": "data/private_infra/global_energy_mix.json", # noqa: E501
"carbon_intensity_per_source_path": "data/private_infra/carbon_intensity_per_source.json",
Expand Down
10 changes: 9 additions & 1 deletion docs/explanation/methodology.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,19 @@ reports a region in one of them:

| Country | Granularity | Source |
|---------|-------------|--------|
| United States | State | [Emissions per state, 2016](https://github.com/mlco2/codecarbon/blob/master/codecarbon/data/private_infra/2016/usa_emissions.json) |
| United States | State | [EPA eGRID2023 emission rate per state](https://github.com/mlco2/codecarbon/blob/master/codecarbon/data/private_infra/2023/usa_emissions.json) |
| Canada | Province | [Energy mix per province, 2023](https://github.com/mlco2/codecarbon/blob/master/codecarbon/data/private_infra/2023/canada_energy_mix.json) |
| Sweden, Norway, Finland | Electricity bidding zone (SE1-SE4, NO1-NO5, FI) | [ENTSO-E generation mix, 2025](https://github.com/mlco2/codecarbon/blob/master/codecarbon/data/private_infra/nordic_emissions.json) |
| China | Province (30 provinces, municipalities and autonomous regions) | [MEE/NBS Announcement 2025 No. 47, 2023 factors](https://github.com/mlco2/codecarbon/blob/master/codecarbon/data/private_infra/2023/china_provincial_emissions.json) |

For the United States, the values are the eGRID2023 state annual CO₂eq
total output emission rates published by the U.S. Environmental Protection
Agency ([source](https://www.epa.gov/egrid/download-data)). They range from
24 gCO₂eq/kWh in Vermont to 893 gCO₂eq/kWh in West Virginia, with a national
value of 350 gCO₂eq/kWh. To update them when EPA publishes a new edition,
download the eGRID data workbook and run
`uv run --with openpyxl python codecarbon/data/private_infra/update_usa_emissions.py <workbook> --year <year>`.

For China, the values are the official provincial average electricity
CO₂ emission factors published by the Ministry of Ecology and
Environment and the National Bureau of Statistics
Expand Down
Loading
Loading