11from ogphl import macro_params , income
22from ogphl import input_output as io
33import os
4+ import warnings
45import numpy as np
56import datetime
6- from ogcore import demographics
77
88UN_COUNTRY_CODE = "608"
99
@@ -18,14 +18,19 @@ def __init__(
1818 macro_data_end_year = datetime .datetime (2023 , 1 , 1 ),
1919 demographic_data_path = None ,
2020 output_path = None ,
21+ update_from_api = False ,
2122 ):
2223 """
2324 Constructor for the Calibration class.
2425
2526 Args:
2627 p (OG-Core Specifications object): model parameters
28+ macro_data_start_year (datetime): start date for macro data
29+ macro_data_end_year (datetime): end date for macro data
2730 demographic_data_path (str): path to save demographic data
2831 output_path (str): path to save output to
32+ update_from_api (bool): Set True to pull updated data from
33+ online sources
2934
3035 Returns:
3136 None
@@ -36,70 +41,100 @@ def __init__(
3641 if not os .path .exists (output_path ):
3742 os .makedirs (output_path )
3843
44+ # Initialize with overlay values only. Existing values on p are the
45+ # baseline from the packaged defaults.
46+ self .macro_params = {}
47+ self .demographic_params = {}
48+ self .e = None
49+ self .alpha_c = np .array ([1.0 ]) if p .I == 1 else None
50+ self .io_matrix = np .array ([[1.0 ]]) if p .M == 1 else None
51+
52+ if not update_from_api :
53+ return
54+
3955 # Macro estimation
40- self .macro_params = macro_params .get_macro_params (
41- macro_data_start_year , macro_data_end_year
42- )
56+ try :
57+ self .macro_params = macro_params .get_macro_params (
58+ macro_data_start_year ,
59+ macro_data_end_year ,
60+ update_from_api = update_from_api ,
61+ )
62+ except Exception as exc :
63+ warnings .warn (f"Macro params update failed: { exc } " , stacklevel = 2 )
4364
4465 # io matrix and alpha_c
45- if p .I > 1 : # no need if just one consumption good
46- alpha_c_dict = io .get_alpha_c ()
47- # check that model dimensions are consistent with alpha_c
48- assert p .I == len (list (alpha_c_dict .keys ()))
49- self .alpha_c = np .array (list (alpha_c_dict .values ()))
50- else :
51- self .alpha_c = np .array ([1.0 ])
52- if p .M > 1 : # no need if just one production good
53- io_df = io .get_io_matrix ()
54- # check that model dimensions are consistent with io_matrix
55- assert p .M == len (list (io_df .keys ()))
56- self .io_matrix = io_df .values
57- else :
58- self .io_matrix = np .array ([[1.0 ]])
59-
60- # demographics
61- self .demographic_params = demographics .get_pop_objs (
62- p .E ,
63- p .S ,
64- p .T ,
65- 0 ,
66- 99 ,
67- country_id = UN_COUNTRY_CODE ,
68- initial_data_year = p .start_year - 1 ,
69- final_data_year = p .start_year + 1 ,
70- GraphDiag = False ,
71- download_path = demographic_data_path ,
72- )
73-
74- # demographics for 80 period lives (needed for getting e below)
75- demog80 = demographics .get_pop_objs (
76- 20 ,
77- 80 ,
78- p .T ,
79- 0 ,
80- 99 ,
81- country_id = UN_COUNTRY_CODE ,
82- initial_data_year = p .start_year - 1 ,
83- final_data_year = p .start_year + 1 ,
84- GraphDiag = False ,
85- )
86-
87- # earnings profiles
88- self .e = income .get_e_interp (
89- p .E ,
90- p .S ,
91- p .J ,
92- p .lambdas ,
93- demog80 ["omega_SS" ],
94- )
66+ if p .I > 1 :
67+ try :
68+ alpha_c_dict = io .get_alpha_c ()
69+ # check that model dimensions are consistent with alpha_c
70+ assert p .I == len (list (alpha_c_dict .keys ()))
71+ self .alpha_c = np .array (list (alpha_c_dict .values ()))
72+ except Exception as exc :
73+ warnings .warn (f"alpha_c update failed: { exc } " , stacklevel = 2 )
74+ if p .M > 1 :
75+ try :
76+ io_df = io .get_io_matrix ()
77+ # check that model dimensions are consistent with io_matrix
78+ assert p .M == len (list (io_df .keys ()))
79+ self .io_matrix = io_df .values
80+ except Exception as exc :
81+ warnings .warn (f"io_matrix update failed: { exc } " , stacklevel = 2 )
82+
83+ # Demographics and income are atomic because e depends on demography.
84+ try :
85+ from ogcore import demographics
86+
87+ self .demographic_params = demographics .get_pop_objs (
88+ p .E ,
89+ p .S ,
90+ p .T ,
91+ 0 ,
92+ 99 ,
93+ country_id = UN_COUNTRY_CODE ,
94+ initial_data_year = p .start_year - 1 ,
95+ final_data_year = p .start_year + 1 ,
96+ GraphDiag = False ,
97+ download_path = demographic_data_path ,
98+ )
99+
100+ # demographics for 80 period lives (needed for getting e below)
101+ demog80 = demographics .get_pop_objs (
102+ 20 ,
103+ 80 ,
104+ p .T ,
105+ 0 ,
106+ 99 ,
107+ country_id = UN_COUNTRY_CODE ,
108+ initial_data_year = p .start_year - 1 ,
109+ final_data_year = p .start_year + 1 ,
110+ GraphDiag = False ,
111+ )
112+
113+ # earnings profiles
114+ self .e = income .get_e_interp (
115+ p .E ,
116+ p .S ,
117+ p .J ,
118+ p .lambdas ,
119+ demog80 ["omega_SS" ],
120+ )
121+ except Exception as exc :
122+ warnings .warn (
123+ f"Demographics/income update failed: { exc } " , stacklevel = 2
124+ )
125+ self .demographic_params = {}
126+ self .e = None
95127
96128 # method to return all newly calibrated parameters in a dictionary
97129 def get_dict (self ):
98- dict = {}
99- dict .update (self .macro_params )
100- dict ["e" ] = self .e
101- dict ["alpha_c" ] = self .alpha_c
102- dict ["io_matrix" ] = self .io_matrix
103- dict .update (self .demographic_params )
104-
105- return dict
130+ d = {}
131+ d .update (self .macro_params )
132+ d .update (self .demographic_params )
133+ if self .e is not None :
134+ d ["e" ] = self .e
135+ if self .alpha_c is not None :
136+ d ["alpha_c" ] = self .alpha_c
137+ if self .io_matrix is not None :
138+ d ["io_matrix" ] = self .io_matrix
139+
140+ return d
0 commit comments