-
Notifications
You must be signed in to change notification settings - Fork 11
SESIT: Industry carbon tax #94
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
9c68dfa
d2792ad
1acb72f
ff20778
d2a3dba
87b65d6
87ac33b
ea56671
dec3d60
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| from macro_data.readers.policy_data.obps_can_reader import OBPSCANData, OBPSCANReader | ||
|
|
||
| __all__ = ["OBPSCANData", "OBPSCANReader"] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| """Reader and container for Canada Output-Based Pricing System (OBPS) policy data.""" | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| from dataclasses import dataclass | ||
| from pathlib import Path | ||
| from typing import Optional | ||
|
|
||
| import pandas as pd | ||
|
|
||
|
|
||
| @dataclass | ||
| class OBPSCANData: | ||
| """Container for Canada OBPS policy tables loaded from CSV files. | ||
|
|
||
| Attributes: | ||
| df_rates: Carbon price trajectory. Rows are years; columns are | ||
| 'Date' plus one column per province/jurisdiction code. | ||
| df_policy: Per-industry emission standards. Must have columns | ||
| 'Industry', 'reduction_factor', and 'tightening_rate'. | ||
| df_policy_elec: Optional electricity-specific tightening rates. | ||
| Same structure as df_policy but for electricity sectors only. | ||
| """ | ||
|
|
||
| df_rates: pd.DataFrame | ||
| df_policy: pd.DataFrame | ||
| df_policy_elec: Optional[pd.DataFrame] = None | ||
|
|
||
|
|
||
| @dataclass | ||
| class OBPSCANReader: | ||
| """Reader for Canada OBPS CSV data files. | ||
|
|
||
| CSV formats | ||
| ----------- | ||
| rates_path: | ||
| Date, CAN, CAN_AB, CAN_BC, ... | ||
| 2014, 15.0, 10.0, 12.0, ... | ||
| 2015, 20.0, 15.0, 15.0, ... | ||
|
|
||
| policy_path: | ||
| Industry, reduction_factor, tightening_rate | ||
| B05a, 0.80, 0.02 | ||
| C19, 0.75, 0.02 | ||
|
|
||
| policy_elec_path (optional): | ||
| same structure as policy_path but for electricity sectors. | ||
| """ | ||
|
|
||
| obps_data: Optional[OBPSCANData] = None | ||
|
|
||
| @classmethod | ||
| def read_from_raw_data( | ||
| cls, | ||
| rates_path: Path | str, | ||
| policy_path: Path | str, | ||
| policy_elec_path: Optional[Path | str] = None, | ||
| ) -> OBPSCANReader: | ||
| """Load OBPS data from CSV files. | ||
|
|
||
| Args: | ||
| rates_path: Path to carbon price rates CSV. | ||
| policy_path: Path to per-industry policy values CSV. | ||
| policy_elec_path: Optional path to electricity-specific CSV. | ||
|
|
||
| Returns: | ||
| OBPSCANReader with loaded OBPSCANData, or obps_data=None if any | ||
| required file is absent. | ||
| """ | ||
| rates_path = Path(rates_path) | ||
| policy_path = Path(policy_path) | ||
|
|
||
| if not rates_path.exists() or not policy_path.exists(): | ||
| return cls(obps_data=None) | ||
|
|
||
| df_rates = pd.read_csv(rates_path) | ||
| df_policy = pd.read_csv(policy_path) | ||
|
|
||
| df_policy_elec = None | ||
| if policy_elec_path is not None: | ||
| policy_elec_path = Path(policy_elec_path) | ||
| if policy_elec_path.exists(): | ||
| df_policy_elec = pd.read_csv(policy_elec_path) | ||
|
|
||
| return cls(obps_data=OBPSCANData(df_rates=df_rates, df_policy=df_policy, df_policy_elec=df_policy_elec)) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -39,6 +39,7 @@ class CountryConfiguration(BaseModel): | |
| assume_zero_noise: bool = False | ||
| use_emission_multiplier: bool = False | ||
| CH4_production_emissions_only: bool = False | ||
| use_obps_reg: bool = False | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Generalization -- the main thing to address before this is reusable. Canada specifics are nicely sealed in the A thin |
||
|
|
||
| @classmethod | ||
| def n_industry_default( | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two notes on how the tax enters price-setting:
base_prices*ratio + tax) is theSectorExogenousPriceSetter. InDefaultPriceSetterthe tax only shiftsaverage_price_by_firm, which feeds the cost-push ratio -- so for default sectors a positive carbon tax can actually nudge the price down via the cost-push channel, and the-good_pricesfloor is largely inert there. Worth confirming the intended sign of the price response for non-exogenous sectors.ExogenousPriceSetter.compute_pricedidn't get theextra_marginal_taxeskwarg that the siblings did; if OBPS is ever combined with that setter,firms.compute_priceforwarding the kwarg willTypeError. Add it (ignored) for signature consistency.