Skip to content
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

Clean up for example scripts and macro_params.py, pass macro data date ranges, #71

Merged
merged 15 commits into from
Aug 5, 2024
Merged
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
include ogzaf/ogzaf_default_parameters.json
include ogzaf/ogzaf_default_parameters_multisector.json
56 changes: 19 additions & 37 deletions examples/run_og_zaf.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,18 @@
import json
import time
import copy
import importlib.resources
import matplotlib.pyplot as plt
from ogzaf.calibrate import Calibration
from ogcore.parameters import Specifications
from ogcore import output_tables as ot
from ogcore import output_plots as op
from ogcore.execute import runner
from ogcore.utils import safe_read_pickle, param_dump_json
from ogcore.utils import safe_read_pickle
from ogzaf.utils import is_connected

# Use a custom matplotlib style file for plots
style_file_url = (
"https://raw.githubusercontent.com/PSLmodels/OG-Core/"
+ "master/ogcore/OGcorePlots.mplstyle"
)
plt.style.use(style_file_url)
plt.style.use("ogcore.OGcorePlots")


def main():
Expand All @@ -30,8 +28,9 @@ def main():

# Directories to save data
CUR_DIR = os.path.dirname(os.path.realpath(__file__))
base_dir = os.path.join(CUR_DIR, "OG-ZAF-Example", "OUTPUT_BASELINE")
reform_dir = os.path.join(CUR_DIR, "OG-ZAF-Example", "OUTPUT_REFORM")
save_dir = os.path.join(CUR_DIR, "OG-ZAF-Example")
base_dir = os.path.join(save_dir, "OUTPUT_BASELINE")
reform_dir = os.path.join(save_dir, "OUTPUT_REFORM")

"""
---------------------------------------------------------------------------
Expand All @@ -46,33 +45,16 @@ def main():
output_base=base_dir,
)
# Update parameters for baseline from default json file
p.update_specifications(
json.load(
open(
os.path.join(
CUR_DIR, "..", "ogzaf", "ogzaf_default_parameters.json"
)
)
)
)
with importlib.resources.open_text(
"ogzaf", "ogzaf_default_parameters.json"
) as file:
defaults = json.load(file)
p.update_specifications(defaults)
# Update parameters from calibrate.py Calibration class
c = Calibration(p)
updated_params = c.get_dict()
p.tax_func_type = "linear"
p.age_specific = False
p.update_specifications(updated_params)
# set underlying growth rate to zero, as value from data is negative
p.g_y = 0.0
# set tax rates
p.update_specifications(
{
"cit_rate": [[0.27]],
"etr_params": [[[0.22]]],
"mtrx_params": [[[0.31]]],
"mtry_params": [[[0.25]]],
"tau_c": [[0.15]],
}
)
if is_connected(): # only update if connected to internet
c = Calibration(p)
updated_params = c.get_dict()
p.update_specifications(updated_params)

# Run model
start_time = time.time()
Expand All @@ -90,7 +72,7 @@ def main():
p2.baseline = False
p2.output_base = reform_dir

# additional parameters to change
# Parameter change for the reform run
updated_params_ref = {
"cit_rate": [[0.30]],
}
Expand Down Expand Up @@ -128,12 +110,12 @@ def main():

# create plots of output
op.plot_all(
base_dir, reform_dir, os.path.join(CUR_DIR, "OG-ZAF_example_plots")
base_dir, reform_dir, os.path.join(save_dir, "OG-ZAF_example_plots")
)

print("Percentage changes in aggregates:", ans)
# save percentage change output to csv file
ans.to_csv("ogzaf_example_output.csv")
ans.to_csv(os.path.join(save_dir, "OG-ZAF_example_output.csv"))


if __name__ == "__main__":
Expand Down
63 changes: 24 additions & 39 deletions examples/run_og_zaf_multiple_industry.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,29 @@
import json
import time
import copy
import numpy as np

# from taxcalc import Calculator
from ogzaf.calibrate import Calibration
import importlib.resources
import matplotlib.pyplot as plt
from ogcore.parameters import Specifications
from ogcore import output_tables as ot
from ogcore import output_plots as op
from ogcore.execute import runner
from ogcore.utils import safe_read_pickle, param_dump_json

# Use a custom matplotlib style file for plots
plt.style.use("ogcore.OGcorePlots")


def main():
# Define parameters to use for multiprocessing
client = Client()
num_workers = min(multiprocessing.cpu_count(), 7)
client = Client(n_workers=num_workers, threads_per_worker=1)
print("Number of workers = ", num_workers)

# Directories to save data
CUR_DIR = os.path.dirname(os.path.realpath(__file__))
base_dir = os.path.join(CUR_DIR, "OG-ZAF-CIT_Example", "OUTPUT_BASELINE")
reform_dir = os.path.join(CUR_DIR, "OG-ZAF-CIT_Example", "OUTPUT_REFORM")
save_dir = os.path.join(CUR_DIR, "OG-ZAF-MultipleIndustry-example")
base_dir = os.path.join(save_dir, "OUTPUT_BASELINE")
reform_dir = os.path.join(save_dir, "OUTPUT_REFORM")

"""
---------------------------------------------------------------------------
Expand All @@ -41,32 +43,11 @@ def main():
output_base=base_dir,
)
# Update parameters for baseline from default json file
p.update_specifications(
json.load(
open(
os.path.join(
CUR_DIR, "..", "ogzaf", "ogzaf_default_parameters.json"
)
)
)
)
# Update parameters from calibrate.py Calibration class
p.M = 4
p.I = 5
c = Calibration(p)
updated_params_tax = {
# order of industries is primary, energy, tertiary, secondary ex energy
"Z": [[0.5, 0.4, 1.7, 1.0]],
"epsilon": [1.0, 1.0, 1.0, 1.0],
"gamma": [0.67, 0.50, 0.45, 0.53],
"gamma_g": [0.0, 0.0, 0.0, 0.0],
"alpha_c": c.alpha_c,
"io_matrix": c.io_matrix,
}
p.update_specifications(updated_params_tax)

# dump params to json
param_dump_json(p, os.path.join(base_dir, "model_params.json"))
with importlib.resources.open_text(
"ogzaf", "ogzaf_default_parameters_multisector.json"
) as file:
defaults = json.load(file)
p.update_specifications(defaults)

# Run model
start_time = time.time()
Expand All @@ -84,12 +65,14 @@ def main():
p2.baseline = False
p2.output_base = reform_dir

# additional parameters to change
# Example reform is a corp tax rate cut (phased in) for all
# industries EXCEPT for secondary ex energy, which has a one point
# increae in the CIT rate
updated_params_ref = {
"cit_rate": [
[0.28, 0.28, 0.28, 0.28],
[0.28, 0.28, 0.28, 0.28],
[0.27, 0.27, 0.27, 0.27],
[0.27, 0.27, 0.27, 0.28],
[0.26, 0.26, 0.26, 0.28],
[0.25, 0.25, 0.25, 0.28],
],
"baseline_spending": True,
}
Expand Down Expand Up @@ -129,12 +112,14 @@ def main():
op.plot_all(
base_dir,
reform_dir,
os.path.join(CUR_DIR, "OG-ZAF_CIT_multi_industry_plots"),
os.path.join(save_dir, "OG-ZAF-MultipleIndustry-example_plots"),
)

print("Percentage changes in aggregates:", ans)
# save percentage change output to csv file
ans.to_csv("ogzaf_CIT_multi_industry_output.csv")
ans.to_csv(
os.path.join(save_dir, "OG-ZAF-MultipleIndustry-example_output.csv")
)


if __name__ == "__main__":
Expand Down
16 changes: 6 additions & 10 deletions ogzaf/calibrate.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from ogzaf import input_output as io
import os
import numpy as np
import datetime
from ogcore import demographics


Expand All @@ -11,8 +12,8 @@ class Calibration:
def __init__(
self,
p,
estimate_tax_functions=False,
estimate_chi_n=False,
macro_data_start_year=datetime.datetime(1947, 1, 1),
macro_data_end_year=datetime.date.today(),
demographic_data_path=None,
output_path=None,
):
Expand All @@ -21,9 +22,6 @@ def __init__(

Args:
p (OG-Core Specifications object): model parameters
estimate_tax_functions (bool): whether to estimate tax
function parameters
estimate_chi_n (bool): whether to estimate chi_n
demographic_data_path (str): path to save demographic data
output_path (str): path to save output to

Expand All @@ -35,11 +33,11 @@ def __init__(
if output_path is not None:
if not os.path.exists(output_path):
os.makedirs(output_path)
self.estimate_tax_functions = estimate_tax_functions
self.estimate_chi_n = estimate_chi_n

# Macro estimation
self.macro_params = macro_params.get_macro_params()
self.macro_params = macro_params.get_macro_params(
macro_data_start_year, macro_data_end_year
)

# io matrix and alpha_c
if p.I > 1: # no need if just one consumption good
Expand Down Expand Up @@ -96,8 +94,6 @@ def __init__(
# method to return all newly calibrated parameters in a dictionary
def get_dict(self):
dict = {}
# if self.estimate_chi_n:
# dict["chi_n"] = self.chi_n
dict.update(self.macro_params)
dict["e"] = self.e
dict["alpha_c"] = self.alpha_c
Expand Down
18 changes: 11 additions & 7 deletions ogzaf/input_output.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import pandas as pd
import numpy as np
from ogzaf.utils import is_connected
from ogzaf.constants import CONS_DICT, PROD_DICT

"""
Expand All @@ -8,13 +9,16 @@
# Read in SAM file
storage_options = {"User-Agent": "Mozilla/5.0"}
SAM_path = "https://www.wider.unu.edu/sites/default/files/Data/SASAM-2015-Data-Resource.xlsx"
SAM = pd.read_excel(
SAM_path,
sheet_name="Micro SAM 2015",
skiprows=6,
index_col=0,
storage_options=storage_options,
)
if is_connected():
SAM = pd.read_excel(
SAM_path,
sheet_name="Micro SAM 2015",
skiprows=6,
index_col=0,
storage_options=storage_options,
)
else:
SAM = None


def get_alpha_c(sam=SAM, cons_dict=CONS_DICT):
Expand Down
Loading
Loading