diff --git a/ogcore/aggregates.py b/ogcore/aggregates.py index 63b2a94a6..3b1ed0f73 100644 --- a/ogcore/aggregates.py +++ b/ogcore/aggregates.py @@ -133,8 +133,10 @@ def get_B(b, p, method, preTP): if preTP: part1 = b * np.transpose(p.omega_S_preTP * p.lambdas) omega_extended = np.append(p.omega_S_preTP[1:], [0.0]) - imm_extended = np.append(p.imm_rates[0, 1:], [0.0]) - pop_growth_rate = p.g_n[0] + imm_extended = np.append( + p.imm_rates_pre_TP[1:], [0.0] + ) + pop_growth_rate = p.g_n_pretP else: part1 = b * np.transpose(p.omega_SS * p.lambdas) omega_extended = np.append(p.omega_SS[1:], [0.0]) @@ -189,8 +191,8 @@ def get_BQ(r, b_splus1, j, p, method, preTP): if method == "SS": if preTP: omega = p.omega_S_preTP - pop_growth_rate = p.g_n[0] - rho = p.rho[0, :] + pop_growth_rate = p.g_n_preTP + rho = p.rho_preTP else: omega = p.omega_SS pop_growth_rate = p.g_n_ss @@ -206,7 +208,7 @@ def get_BQ(r, b_splus1, j, p, method, preTP): p.omega_S_preTP.reshape(1, p.S), p.omega[: p.T - 1, :], axis=0 ) rho = np.append( - p.rho[0, :].reshape(1, p.S), p.rho[: p.T - 1, :], axis=0 + p.rho_preTP.reshape(1, p.S), p.rho[: p.T - 1, :], axis=0 ) if j is not None: diff --git a/ogcore/default_parameters.json b/ogcore/default_parameters.json index e6c7cbd1a..73abdbd7b 100644 --- a/ogcore/default_parameters.json +++ b/ogcore/default_parameters.json @@ -4547,6 +4547,24 @@ } } }, + "g_n_preTP": { + "title": "Population growth rate from year before model start to start year", + "description": "Population growth rate from year before model start to start year.", + "section_1": "Demographic Parameters", + "notes": "", + "type": "float", + "value": [ + { + "value": 0.0012907765315350872 + } + ], + "validators": { + "range": { + "min": -1.0, + "max": 1.0 + } + } + }, "imm_rates": { "title": "Immigration rates over the time path.", "description": "Immigration rates over the time path.", @@ -4568,6 +4586,45 @@ } } }, + "imm_rates_pre_TP": { + "title": "Immigration rates in period before model start year", + "description": "Immigration rates in period before model start year.", + "section_1": "Demographic Parameters", + "notes": "", + "type": "float", + "number_dims": 1, + "value": [ + { + "value": + [ 6.21124324e-03, 6.69539127e-03, 7.24160599e-03, 7.59057707e-03, + 7.64614775e-03, 7.51951110e-03, 7.06681489e-03, 6.56429771e-03, + 6.07319754e-03, 5.50700033e-03, 4.94732741e-03, 4.54958259e-03, + 4.23425001e-03, 3.97403995e-03, 3.67752183e-03, 3.38021287e-03, + 3.00514338e-03, 2.71916344e-03, 2.41686669e-03, 2.13548533e-03, + 1.86850952e-03, 1.63930855e-03, 1.45713458e-03, 1.34212247e-03, + 1.27164811e-03, 9.88138261e-04, 8.42267890e-04, 7.97801211e-04, + 6.63231805e-04, 4.87948389e-04, 4.32979019e-04, 5.60040782e-04, + 4.55369916e-04, 4.13717216e-04, 4.55029226e-04, 4.52104109e-04, + 5.58645176e-04, 6.14631276e-04, 5.66684121e-04, 5.11408015e-04, + 4.68968748e-04, 4.86541731e-04, 1.87084644e-04, -2.33525940e-05, + 1.21315737e-03, 1.05324177e-03, 8.29011129e-07, -1.80456466e-04, + 6.44696838e-04, 1.08838720e-03, 6.18137660e-04, 4.41473826e-04, + 6.10186803e-04, 6.58633423e-04, 5.63207404e-04, 5.34295717e-04, + 6.00114993e-04, 6.29050763e-04, 8.43098879e-04, 9.20493620e-04, + 9.68908696e-04, 1.26374022e-03, 1.60616956e-03, 1.72840304e-03, + 1.50429547e-03, 1.03459297e-03, 8.01449649e-04, 9.28625040e-04, + 1.60993336e-03, 2.23227102e-03, 3.53451125e-03, 5.32480275e-03, + 7.84622608e-03, 1.08220386e-02, 1.30810434e-02, 1.64519720e-02, + 1.88010017e-02, 2.12725905e-02, 2.17955114e-02, 1.92400972e-02] + } + ], + "validators": { + "range": { + "min": -1.0, + "max": 1.0 + } + } + }, "rho": { "title": "Age-specific mortality rates.", "description": "Age-specific mortality rates.", @@ -4587,6 +4644,44 @@ } } }, + "rho_preTP": { + "title": "Age-specific mortality rates.", + "description": "Age-specific mortality rates.", + "section_1": "Demographic Parameters", + "notes": "", + "type": "float", + "number_dims": 1, + "value": [ + { + "value": [7.32853396e-04, 8.17119742e-04, 8.78872967e-04, 9.11652521e-04, + 9.22980233e-04, 9.27340681e-04, 9.35710239e-04, 9.50095370e-04, + 9.75973557e-04, 1.01035546e-03, 1.04974597e-03, 1.08965056e-03, + 1.12905646e-03, 1.16544560e-03, 1.20432393e-03, 1.25117739e-03, + 1.31100453e-03, 1.38282557e-03, 1.46963538e-03, 1.57292023e-03, + 1.69015991e-03, 1.82531513e-03, 1.98785868e-03, 2.18224842e-03, + 2.40545835e-03, 2.64949570e-03, 2.91235990e-03, 3.19652189e-03, + 3.50144041e-03, 3.82658531e-03, 4.17597720e-03, 4.54600008e-03, + 4.92938669e-03, 5.32344068e-03, 5.73216261e-03, 6.18294920e-03, + 6.66506301e-03, 7.14289275e-03, 7.60533472e-03, 8.07929361e-03, + 8.60718380e-03, 9.21954043e-03, 9.91697732e-03, 1.07137947e-02, + 1.16186807e-02, 1.26511756e-02, 1.38062007e-02, 1.50692314e-02, + 1.64399087e-02, 1.79462854e-02, 1.96828400e-02, 2.16430913e-02, + 2.37466335e-02, 2.59837193e-02, 2.84282734e-02, 3.12585980e-02, + 3.45111290e-02, 3.80870625e-02, 4.19924732e-02, 4.63268386e-02, + 5.13310180e-02, 5.70418578e-02, 6.33201548e-02, 7.01769632e-02, + 7.77688358e-02, 8.62903314e-02, 9.59061899e-02, 1.06724255e-01, + 1.18798575e-01, 1.32125256e-01, 1.46682823e-01, 1.62432478e-01, + 1.79326966e-01, 1.97313414e-01, 2.16339448e-01, 2.35357633e-01, + 2.54059844e-01, 2.72119171e-01, 2.89195180e-01, 1.00000000e+00] + } + ], + "validators": { + "range": { + "min": 0.0, + "max": 1.0 + } + } + }, "etr_params": { "title": "Effective tax rate function parameters.", "description": "Effective tax rate function parameters.", diff --git a/ogcore/demographics.py b/ogcore/demographics.py index ce8a3e660..dcf61e16f 100644 --- a/ogcore/demographics.py +++ b/ogcore/demographics.py @@ -775,9 +775,12 @@ def get_pop_objs( path, length T + S """ + start_data_year = initial_data_year - 1 # grab data from one year + T = T + 1 # add one period to T to account for period -1 pop + # before initial so have pre-start year population distribution # TODO: this function does not generalize with T. # It assumes one model period is equal to one calendar year in the - # time dimesion (it does adjust for S, however) + # time dimension (it does adjust for S, however) T0 = ( final_data_year - initial_data_year + 1 ) # number of periods until constant fertility and mortality rates @@ -788,8 +791,8 @@ def get_pop_objs( final_data_year, ) assert E + S <= max_age - min_age + 1 - assert initial_data_year >= 2011 and initial_data_year <= 2100 - 1 - assert final_data_year >= 2011 and final_data_year <= 2100 - 1 + assert initial_data_year >= 2012 and initial_data_year <= 2100 - 1 + assert final_data_year >= 2012 and final_data_year <= 2100 - 1 # Ensure that the last year of data used is before SS transition assumed # Really, it will need to be well before this assert final_data_year > initial_data_year @@ -810,7 +813,7 @@ def get_pop_objs( min_age, max_age, country_id, - initial_data_year, + start_data_year, final_data_year, download_path=download_path, ) @@ -839,7 +842,7 @@ def get_pop_objs( min_age, max_age, country_id, - initial_data_year, + start_data_year, final_data_year, download_path=download_path, ) @@ -890,7 +893,7 @@ def get_pop_objs( initial_pop, pre_pop_dist, country_id, - initial_data_year, + start_data_year, final_data_year, download_path=download_path, ) @@ -901,7 +904,7 @@ def get_pop_objs( min_age, max_age, country_id=country_id, - start_year=initial_data_year, + start_year=start_data_year, end_year=final_data_year, download_path=download_path, ) @@ -933,7 +936,7 @@ def get_pop_objs( infmort_rates, pop_2D, country_id, - initial_data_year, + start_data_year, final_data_year, download_path=download_path, ) @@ -1145,7 +1148,6 @@ def get_pop_objs( omega_path_lev[0, -S:].sum() - pre_pop_EpS[-S:].sum() ) / pre_pop_EpS[-S:].sum() g_n_path[fixper + 1 :] = g_n_SS - omega_S_preTP = pre_pop_EpS[-S:] / pre_pop_EpS[-S:].sum() imm_rates_mat = np.concatenate( ( imm_rates_orig[:fixper, E:], @@ -1156,6 +1158,10 @@ def get_pop_objs( ), axis=0, ) + # compute pop objects for the year before the model start year + # population distribution + # TODO: can delete this and proobalby any "pre_pop" calculations above + omega_S_preTP = pre_pop_EpS[-S:] / pre_pop_EpS[-S:].sum() if GraphDiag: # Check whether original SS population distribution is close to @@ -1304,13 +1310,16 @@ def get_pop_objs( # Return objects in a dictionary pop_dict = { - "omega": omega_path_S, + "omega": omega_path_S[1:, :], "g_n_ss": g_n_SS, "omega_SS": omega_SSfx[-S:] / omega_SSfx[-S:].sum(), - "rho": mort_rates_S, - "g_n": g_n_path, - "imm_rates": imm_rates_mat, - "omega_S_preTP": omega_S_preTP, + "rho": mort_rates_S[1:, :], + "g_n": g_n_path[1:], + "imm_rates": imm_rates_mat[1:, :], + "omega_S_preTP": omega_path_S[0, :], + "imm_rates_preTP": imm_rates_mat[0, :], + "rho_preTP": mort_rates_S[0, :], + "g_m_preTP": g_n_path[0], } return pop_dict diff --git a/ogcore/parameters.py b/ogcore/parameters.py index 0134d21fc..aa3e12d3c 100644 --- a/ogcore/parameters.py +++ b/ogcore/parameters.py @@ -329,6 +329,8 @@ def compute_default_params(self): np.reshape(self.omega_SS, (1, self.S)), (self.T + self.S, 1) ) self.omega_S_preTP = self.omega_SS + self.imm_rates_preTP = np.zeros(self.S) + self.rho_preTP = self.rho[0, :] # Create time series of stationarized UBI transfers self.ubi_nom_array = self.get_ubi_nom_objs() diff --git a/tests/test_demographics.py b/tests/test_demographics.py index 7ea0e2167..da149f86b 100644 --- a/tests/test_demographics.py +++ b/tests/test_demographics.py @@ -558,10 +558,10 @@ def test_data_download(tmpdir): T, 0, 99, - fert_rates=fert_rates, - mort_rates=mort_rates, - infmort_rates=infmort_rates, - imm_rates=imm_rates, + fert_rates=fert_rates[1:, :], + mort_rates=mort_rates[1:, :], + infmort_rates=infmort_rates[1:], + imm_rates=imm_rates[1:, :], infer_pop=True, pop_dist=pop_dist[0, :].reshape(1, E + S), pre_pop_dist=pre_pop_dist,