def test_Calculator_mtr_when_PT_rates_differ(): reform = {2013: {'_II_rt1': [0.40], '_II_rt2': [0.40], '_II_rt3': [0.40], '_II_rt4': [0.40], '_II_rt5': [0.40], '_II_rt6': [0.40], '_II_rt7': [0.40], '_PT_rt1': [0.30], '_PT_rt2': [0.30], '_PT_rt3': [0.30], '_PT_rt4': [0.30], '_PT_rt5': [0.30], '_PT_rt6': [0.30], '_PT_rt7': [0.30]}} funit = ( u'RECID,MARS,FLPDYR,e00200,e00200p,e00900,e00900p\n' u'1, 1, 2015, 200000,200000, 100000,100000\n' ) pol1 = Policy() rec1 = Records(pd.read_csv(StringIO(funit))) calc1 = Calculator(policy=pol1, records=rec1) (_, mtr1, _) = calc1.mtr(variable_str='p23250') pol2 = Policy() pol2.implement_reform(reform) rec2 = Records(pd.read_csv(StringIO(funit))) calc2 = Calculator(policy=pol2, records=rec2) (_, mtr2, _) = calc2.mtr(variable_str='p23250') assert np.allclose(mtr1, mtr2, rtol=0.0, atol=1e-06)
def test_consumption_response(cps_subsample): consump = Consumption() mpc = 0.5 consumption_response = {2013: {'_MPC_e20400': [mpc]}} consump.update_consumption(consumption_response) # test incorrect call to response method with pytest.raises(ValueError): consump.response(list(), 1) # test correct call to response method rec = Records.cps_constructor(data=cps_subsample) pre = copy.deepcopy(rec.e20400) consump.response(rec, 1.0) post = rec.e20400 actual_diff = post - pre expected_diff = np.ones(rec.dim) * mpc assert np.allclose(actual_diff, expected_diff) # compute earnings mtr with no consumption response rec = Records.cps_constructor(data=cps_subsample) ided0 = copy.deepcopy(rec.e20400) calc0 = Calculator(policy=Policy(), records=rec, consumption=None) (mtr0_ptax, mtr0_itax, _) = calc0.mtr(variable_str='e00200p', wrt_full_compensation=False) assert np.allclose(calc0.records.e20400, ided0) # compute earnings mtr with consumption response calc1 = Calculator(policy=Policy(), records=rec, consumption=consump) mtr1_ptax, mtr1_itax, _ = calc1.mtr(variable_str='e00200p', wrt_full_compensation=False) assert np.allclose(calc1.records.e20400, ided0) # confirm that payroll mtr values are no different assert np.allclose(mtr1_ptax, mtr0_ptax) # confirm that all mtr with cons-resp are no greater than without cons-resp assert np.all(np.less_equal(np.around(mtr1_itax, decimals=5), np.around(mtr0_itax, decimals=5))) # confirm that some mtr with cons-resp are less than without cons-resp assert np.any(np.less(mtr1_itax, mtr0_itax))
def test_calculator_mtr_when_PT_rates_differ(): """ Test Calculator mtr method in special case. """ reform = {2013: {'_II_rt1': [0.40], '_II_rt2': [0.40], '_II_rt3': [0.40], '_II_rt4': [0.40], '_II_rt5': [0.40], '_II_rt6': [0.40], '_II_rt7': [0.40], '_PT_rt1': [0.30], '_PT_rt2': [0.30], '_PT_rt3': [0.30], '_PT_rt4': [0.30], '_PT_rt5': [0.30], '_PT_rt6': [0.30], '_PT_rt7': [0.30]}} funit = ( u'RECID,MARS,FLPDYR,e00200,e00200p,e00900,e00900p,extraneous\n' u'1, 1, 2009, 200000,200000, 100000,100000, 9999999999\n' ) rec = Records(pd.read_csv(StringIO(funit))) pol = Policy() calc1 = Calculator(policy=pol, records=rec) (_, mtr1, _) = calc1.mtr(variable_str='p23250') pol.implement_reform(reform) calc2 = Calculator(policy=pol, records=rec) (_, mtr2, _) = calc2.mtr(variable_str='p23250') assert np.allclose(mtr1, mtr2, rtol=0.0, atol=1e-06)
def test_consumption_response(cps_subsample): consump = Consumption() mpc = 0.5 consumption_response = {'MPC_e20400': {2013: mpc}} consump.update_consumption(consumption_response) # test incorrect call to response method with pytest.raises(ValueError): consump.response(list(), 1) # test correct call to response method rec = Records.cps_constructor(data=cps_subsample) pre = copy.deepcopy(rec.e20400) consump.response(rec, 1.0) post = rec.e20400 actual_diff = post - pre expected_diff = np.ones(rec.array_length) * mpc assert np.allclose(actual_diff, expected_diff) # compute earnings mtr with no consumption response rec = Records.cps_constructor(data=cps_subsample) ided0 = copy.deepcopy(rec.e20400) calc0 = Calculator(policy=Policy(), records=rec, consumption=None) (mtr0_ptax, mtr0_itax, _) = calc0.mtr(variable_str='e00200p', wrt_full_compensation=False) assert np.allclose(calc0.array('e20400'), ided0) # compute earnings mtr with consumption response calc1 = Calculator(policy=Policy(), records=rec, consumption=consump) mtr1_ptax, mtr1_itax, _ = calc1.mtr(variable_str='e00200p', wrt_full_compensation=False) assert np.allclose(calc1.array('e20400'), ided0) # confirm that payroll mtr values are no different assert np.allclose(mtr1_ptax, mtr0_ptax) # confirm that all mtr with cons-resp are no greater than without cons-resp assert np.all(np.less_equal(np.around(mtr1_itax, decimals=5), np.around(mtr0_itax, decimals=5))) # confirm that some mtr with cons-resp are less than without cons-resp assert np.any(np.less(mtr1_itax, mtr0_itax))
def test_Calculator_mtr_when_PT_rates_differ(): reform = { 2013: { '_II_rt1': [0.40], '_II_rt2': [0.40], '_II_rt3': [0.40], '_II_rt4': [0.40], '_II_rt5': [0.40], '_II_rt6': [0.40], '_II_rt7': [0.40], '_PT_rt1': [0.30], '_PT_rt2': [0.30], '_PT_rt3': [0.30], '_PT_rt4': [0.30], '_PT_rt5': [0.30], '_PT_rt6': [0.30], '_PT_rt7': [0.30] } } funit = (u'RECID,MARS,FLPDYR,e00200,e00200p,e00900,e00900p,extraneous\n' u'1, 1, 2009, 200000,200000, 100000,100000, 9999999999\n') pol1 = Policy() rec1 = Records(pd.read_csv(StringIO(funit))) calc1 = Calculator(policy=pol1, records=rec1) (_, mtr1, _) = calc1.mtr(variable_str='p23250') pol2 = Policy() pol2.implement_reform(reform) rec2 = Records(pd.read_csv(StringIO(funit))) calc2 = Calculator(policy=pol2, records=rec2) (_, mtr2, _) = calc2.mtr(variable_str='p23250') assert np.allclose(mtr1, mtr2, rtol=0.0, atol=1e-06)
def test_calculator_mtr_when_PT_rates_differ(): """ Test Calculator mtr method in special case. """ reform = { 'II_rt1': {2013: 0.40}, 'II_rt2': {2013: 0.40}, 'II_rt3': {2013: 0.40}, 'II_rt4': {2013: 0.40}, 'II_rt5': {2013: 0.40}, 'II_rt6': {2013: 0.40}, 'II_rt7': {2013: 0.40}, 'PT_rt1': {2013: 0.30}, 'PT_rt2': {2013: 0.30}, 'PT_rt3': {2013: 0.30}, 'PT_rt4': {2013: 0.30}, 'PT_rt5': {2013: 0.30}, 'PT_rt6': {2013: 0.30}, 'PT_rt7': {2013: 0.30} } funit = ( 'RECID,MARS,FLPDYR,e00200,e00200p,e00900,e00900p,extraneous\n' '1, 1, 2009, 200000,200000, 100000,100000, 9999999999\n' ) rec = Records(pd.read_csv(StringIO(funit))) pol = Policy() calc1 = Calculator(policy=pol, records=rec) (_, mtr1, _) = calc1.mtr(variable_str='p23250') pol.implement_reform(reform) calc2 = Calculator(policy=pol, records=rec) (_, mtr2, _) = calc2.mtr(variable_str='p23250') assert np.allclose(mtr1, mtr2, rtol=0.0, atol=1e-06)
def test_consumption_response(puf_1991, weights_1991): consump = Consumption() mpc = 0.5 consumption_response = {2013: {"_MPC_e20400": [mpc]}} consump.update_consumption(consumption_response) # test incorrect call to response method with pytest.raises(ValueError): consump.response(list(), 1) # test correct call to response method recs = Records(data=puf_1991, weights=weights_1991, start_year=2009) pre = copy.deepcopy(recs.e20400) consump.response(recs, 1.0) post = recs.e20400 actual_diff = post - pre expected_diff = np.ones(recs.dim) * mpc assert np.allclose(actual_diff, expected_diff) # compute earnings mtr with no consumption response recs0 = Records(data=puf_1991, weights=weights_1991, start_year=2009) calc0 = Calculator(policy=Policy(), records=recs0, consumption=None) ided0 = copy.deepcopy(recs0.e20400) (mtr0_ptax, mtr0_itax, _) = calc0.mtr(variable_str="e00200p", wrt_full_compensation=False) assert np.allclose(calc0.records.e20400, ided0) # compute earnings mtr with consumption response recs1 = Records(data=puf_1991, weights=weights_1991, start_year=2009) calc1 = Calculator(policy=Policy(), records=recs1, consumption=None) assert np.allclose(calc1.records.e20400, ided0) calc1.consumption.update_consumption(consumption_response) (mtr1_ptax, mtr1_itax, _) = calc1.mtr(variable_str="e00200p", wrt_full_compensation=False) assert np.allclose(calc1.records.e20400, ided0) # confirm that payroll mtr values are no different assert np.allclose(mtr1_ptax, mtr0_ptax) # confirm that all mtr with cons-resp are no greater than without cons-resp assert np.all(np.less_equal(mtr1_itax, mtr0_itax)) # confirm that some mtr with cons-resp are less than without cons-resp assert np.any(np.less(mtr1_itax, mtr0_itax))
def test_calculator_using_nonstd_input(): """ Test Calculator using non-standard input records. """ # check Calculator handling of raw, non-standard input data with no aging pol = Policy() pol.set_year(RAWINPUT_YEAR) # set policy params to input data year nonstd = Records( data=pd.read_csv(StringIO(RAWINPUT_CONTENTS)), start_year=RAWINPUT_YEAR, # set raw input data year gfactors=None, # keeps raw data unchanged weights=None) assert nonstd.array_length == RAWINPUT_FUNITS calc = Calculator(policy=pol, records=nonstd, sync_years=False) # keeps raw data unchanged assert calc.current_year == RAWINPUT_YEAR calc.calc_all() assert calc.weighted_total('e00200') == 0 assert calc.total_weight() == 0 varlist = ['RECID', 'MARS'] dframe = calc.dataframe(varlist) assert isinstance(dframe, pd.DataFrame) assert dframe.shape == (RAWINPUT_FUNITS, len(varlist)) mars = calc.array('MARS') assert isinstance(mars, np.ndarray) assert mars.shape == (RAWINPUT_FUNITS, ) exp_iitax = np.zeros((nonstd.array_length, )) assert np.allclose(calc.array('iitax'), exp_iitax) mtr_ptax, _, _ = calc.mtr(wrt_full_compensation=False) exp_mtr_ptax = np.zeros((nonstd.array_length, )) exp_mtr_ptax.fill(0.153) assert np.allclose(mtr_ptax, exp_mtr_ptax)
def test_calculator_using_nonstd_input(rawinputfile): """ Test Calculator using non-standard input records. """ # check Calculator handling of raw, non-standard input data with no aging pol = Policy() pol.set_year(RAWINPUTFILE_YEAR) # set policy params to input data year nonstd = Records(data=rawinputfile.name, gfactors=None, # keeps raw data unchanged weights=None, start_year=RAWINPUTFILE_YEAR) # set raw input data year assert nonstd.array_length == RAWINPUTFILE_FUNITS calc = Calculator(policy=pol, records=nonstd, sync_years=False) # keeps raw data unchanged assert calc.current_year == RAWINPUTFILE_YEAR calc.calc_all() assert calc.weighted_total('e00200') == 0 assert calc.total_weight() == 0 varlist = ['RECID', 'MARS'] dframe = calc.dataframe(varlist) assert isinstance(dframe, pd.DataFrame) assert dframe.shape == (RAWINPUTFILE_FUNITS, len(varlist)) mars = calc.array('MARS') assert isinstance(mars, np.ndarray) assert mars.shape == (RAWINPUTFILE_FUNITS,) exp_iitax = np.zeros((nonstd.array_length,)) assert np.allclose(calc.array('iitax'), exp_iitax) mtr_ptax, _, _ = calc.mtr(wrt_full_compensation=False) exp_mtr_ptax = np.zeros((nonstd.array_length,)) exp_mtr_ptax.fill(0.153) assert np.allclose(mtr_ptax, exp_mtr_ptax)
def test_calculator_using_nonstd_input(rawinputfile): # check Calculator handling of raw, non-standard input data with no aging pol = Policy() pol.set_year(RAWINPUTFILE_YEAR) # set policy params to input data year nonstd = Records( data=rawinputfile.name, gfactors=None, # keeps raw data unchanged weights=None, start_year=RAWINPUTFILE_YEAR) # set raw input data year assert nonstd.dim == RAWINPUTFILE_FUNITS calc = Calculator(policy=pol, records=nonstd, sync_years=False) # keeps raw data unchanged assert calc.current_year == RAWINPUTFILE_YEAR calc.calc_all() assert calc.weighted_total('e00200') == 0 assert calc.total_weight() == 0 varlist = ['RECID', 'MARS'] pdf = calc.dataframe(varlist) assert isinstance(pdf, pd.DataFrame) assert pdf.shape == (RAWINPUTFILE_FUNITS, len(varlist)) mars = calc.array('MARS') assert isinstance(mars, np.ndarray) assert mars.shape == (RAWINPUTFILE_FUNITS, ) exp_iitax = np.zeros((nonstd.dim, )) assert np.allclose(calc.records.iitax, exp_iitax) mtr_ptax, _, _ = calc.mtr(wrt_full_compensation=False) exp_mtr_ptax = np.zeros((nonstd.dim, )) exp_mtr_ptax.fill(0.153) assert np.allclose(mtr_ptax, exp_mtr_ptax)
def test_mtr_pt_active(puf_subsample): """ Test whether including wages in active income causes MTRs on e00900p and e26270 to be less than -1 (i.e., -100%) """ # pylint: disable=too-many-locals rec = Records(data=puf_subsample) reform_year = 2018 # create current-law Calculator object, calc1 pol1 = Policy() calc1 = Calculator(policy=pol1, records=rec) calc1.advance_to_year(reform_year) calc1.calc_all() mtr1_e00900p = calc1.mtr('e00900p')[2] mtr1_e26270 = calc1.mtr('e26270')[2] assert min(mtr1_e00900p) > -1 assert min(mtr1_e26270) > -1 # change PT rates, calc2 reform2 = {'PT_rt7': {reform_year: 0.35}} pol2 = Policy() pol2.implement_reform(reform2) calc2 = Calculator(policy=pol2, records=rec) calc2.advance_to_year(reform_year) calc2.calc_all() mtr2_e00900p = calc2.mtr('e00900p')[2] mtr2_e26270 = calc2.mtr('e26270')[2] assert min(mtr2_e00900p) > -1 assert min(mtr2_e26270) > -1 # change PT_wages_active_income reform3 = {'PT_wages_active_income': {reform_year: True}} pol3 = Policy() pol3.implement_reform(reform3) calc3 = Calculator(policy=pol3, records=rec) calc3.advance_to_year(reform_year) calc3.calc_all() mtr3_e00900p = calc3.mtr('e00900p')[2] mtr3_e26270 = calc3.mtr('e26270')[2] assert min(mtr3_e00900p) > -1 assert min(mtr3_e26270) > -1 # change PT rates and PT_wages_active_income reform4 = { 'PT_wages_active_income': { reform_year: True }, 'PT_rt7': { reform_year: 0.35 } } pol4 = Policy() pol4.implement_reform(reform4) calc4 = Calculator(policy=pol4, records=rec) calc4.advance_to_year(reform_year) calc4.calc_all() mtr4_e00900p = calc4.mtr('e00900p')[2] mtr4_e26270 = calc4.mtr('e26270')[2] assert min(mtr4_e00900p) > -1 assert min(mtr4_e26270) > -1
def test_Calculator_mtr(): policy = Policy() puf = Records(TAX_DTA, weights=WEIGHTS, start_year=2009) calc = Calculator(policy=policy, records=puf) (mtr_FICA, mtr_IIT, mtr) = calc.mtr() assert type(mtr) == np.ndarray assert np.array_equal(mtr, mtr_FICA) is False assert np.array_equal(mtr_FICA, mtr_IIT) is False
def test_Calculator_mtr(): policy = Policy() puf = Records(TAXDATA, weights=WEIGHTS, start_year=2009) calc = Calculator(policy=policy, records=puf) (mtr_FICA, mtr_IIT, mtr) = calc.mtr() assert type(mtr) == np.ndarray assert np.array_equal(mtr, mtr_FICA) is False assert np.array_equal(mtr_FICA, mtr_IIT) is False
def test_calculator_mtr(cps_subsample): """ Test Calculator mtr method. """ rec = Records.cps_constructor(data=cps_subsample) calcx = Calculator(policy=Policy(), records=rec) calcx.calc_all() combinedx = calcx.array('combined') c00100x = calcx.array('c00100') calc = Calculator(policy=Policy(), records=rec) recs_pre_e00200p = copy.deepcopy(calc.array('e00200p')) (mtr_ptx, mtr_itx, mtr_cmb) = calc.mtr(variable_str='e00200p', zero_out_calculated_vars=True) recs_post_e00200p = calc.array('e00200p') assert np.allclose(recs_post_e00200p, recs_pre_e00200p) assert np.allclose(calc.array('combined'), combinedx) assert np.allclose(calc.array('c00100'), c00100x) assert np.array_equal(mtr_cmb, mtr_ptx) is False assert np.array_equal(mtr_ptx, mtr_itx) is False with pytest.raises(ValueError): calc.mtr(variable_str='bad_income_type') (_, _, mtr_combined) = calc.mtr(variable_str='e00200s', calc_all_already_called=True) assert isinstance(mtr_combined, np.ndarray) (_, _, mtr_combined) = calc.mtr(variable_str='e00650', negative_finite_diff=True, calc_all_already_called=True) assert isinstance(mtr_combined, np.ndarray) (_, _, mtr_combined) = calc.mtr(variable_str='e00900p', calc_all_already_called=True) assert isinstance(mtr_combined, np.ndarray) (_, _, mtr_combined) = calc.mtr(variable_str='e01700', calc_all_already_called=True) assert isinstance(mtr_combined, np.ndarray) (_, _, mtr_combined) = calc.mtr(variable_str='e26270', calc_all_already_called=True) assert isinstance(mtr_combined, np.ndarray) (_, _, mtr_combined) = calc.mtr(variable_str='k1bx14p', calc_all_already_called=True) assert isinstance(mtr_combined, np.ndarray) (_, _, mtr_combined) = calc.mtr(variable_str='e00200p', calc_all_already_called=True) assert np.allclose(mtr_combined, mtr_cmb) assert np.allclose(calc.array('combined'), combinedx) assert np.allclose(calc.array('c00100'), c00100x)
def test_mtr_pt_active(puf_subsample): """ Test whether including wages in active income causes MTRs on e00900p and e26270 to be less than -1 (i.e., -100%) """ # pylint: disable=too-many-locals rec = Records(data=puf_subsample) reform_year = 2018 # create current-law Calculator object, calc1 pol1 = Policy() calc1 = Calculator(policy=pol1, records=rec) calc1.advance_to_year(reform_year) calc1.calc_all() mtr1_e00900p = calc1.mtr('e00900p')[2] mtr1_e26270 = calc1.mtr('e26270')[2] assert min(mtr1_e00900p) > -1 assert min(mtr1_e26270) > -1 # change PT rates, calc2 reform2 = {'PT_rt7': {reform_year: 0.35}} pol2 = Policy() pol2.implement_reform(reform2) calc2 = Calculator(policy=pol2, records=rec) calc2.advance_to_year(reform_year) calc2.calc_all() mtr2_e00900p = calc2.mtr('e00900p')[2] mtr2_e26270 = calc2.mtr('e26270')[2] assert min(mtr2_e00900p) > -1 assert min(mtr2_e26270) > -1 # change PT_wages_active_income reform3 = {'PT_wages_active_income': {reform_year: True}} pol3 = Policy() pol3.implement_reform(reform3) calc3 = Calculator(policy=pol3, records=rec) calc3.advance_to_year(reform_year) calc3.calc_all() mtr3_e00900p = calc3.mtr('e00900p')[2] mtr3_e26270 = calc3.mtr('e26270')[2] assert min(mtr3_e00900p) > -1 assert min(mtr3_e26270) > -1 # change PT rates and PT_wages_active_income reform4 = { 'PT_wages_active_income': {reform_year: True}, 'PT_rt7': {reform_year: 0.35} } pol4 = Policy() pol4.implement_reform(reform4) calc4 = Calculator(policy=pol4, records=rec) calc4.advance_to_year(reform_year) calc4.calc_all() mtr4_e00900p = calc4.mtr('e00900p')[2] mtr4_e26270 = calc4.mtr('e26270')[2] assert min(mtr4_e00900p) > -1 assert min(mtr4_e26270) > -1
def test_Calculator_mtr(): puf = Records(TAXDATA, weights=WEIGHTS, start_year=2009) calc = Calculator(policy=Policy(), records=puf) recs_pre_e00200p = copy.deepcopy(calc.records.e00200p) (mtr_FICA, mtr_IIT, mtr_combined) = calc.mtr(income_type_str='e00200p') recs_post_e00200p = copy.deepcopy(calc.records.e00200p) assert np.allclose(recs_post_e00200p, recs_pre_e00200p) assert type(mtr_combined) == np.ndarray assert np.array_equal(mtr_combined, mtr_FICA) is False assert np.array_equal(mtr_FICA, mtr_IIT) is False with pytest.raises(ValueError): (_, _, mtr_combined) = calc.mtr(income_type_str='bad_income_type') (_, _, mtr_combined) = calc.mtr(income_type_str='e00650', negative_finite_diff=True) assert type(mtr_combined) == np.ndarray (_, _, mtr_combined) = calc.mtr(income_type_str='e00900p') assert type(mtr_combined) == np.ndarray (_, _, mtr_combined) = calc.mtr(income_type_str='e01700') assert type(mtr_combined) == np.ndarray
def test_calculator_mtr(cps_subsample): """ Test Calculator mtr method. """ rec = Records.cps_constructor(data=cps_subsample) calcx = Calculator(policy=Policy(), records=rec) calcx.calc_all() combinedx = calcx.array('combined') c00100x = calcx.array('c00100') calc = Calculator(policy=Policy(), records=rec) recs_pre_e00200p = copy.deepcopy(calc.array('e00200p')) (mtr_ptx, mtr_itx, mtr_cmb) = calc.mtr(variable_str='e00200p', zero_out_calculated_vars=True) recs_post_e00200p = calc.array('e00200p') assert np.allclose(recs_post_e00200p, recs_pre_e00200p) assert np.allclose(calc.array('combined'), combinedx) assert np.allclose(calc.array('c00100'), c00100x) assert np.array_equal(mtr_cmb, mtr_ptx) is False assert np.array_equal(mtr_ptx, mtr_itx) is False with pytest.raises(ValueError): calc.mtr(variable_str='bad_income_type') (_, _, mtr_combined) = calc.mtr(variable_str='e00200s', calc_all_already_called=True) assert isinstance(mtr_combined, np.ndarray) (_, _, mtr_combined) = calc.mtr(variable_str='e00650', negative_finite_diff=True, calc_all_already_called=True) assert isinstance(mtr_combined, np.ndarray) (_, _, mtr_combined) = calc.mtr(variable_str='e00900p', calc_all_already_called=True) assert isinstance(mtr_combined, np.ndarray) (_, _, mtr_combined) = calc.mtr(variable_str='e01700', calc_all_already_called=True) assert isinstance(mtr_combined, np.ndarray) (_, _, mtr_combined) = calc.mtr(variable_str='e26270', calc_all_already_called=True) assert isinstance(mtr_combined, np.ndarray) (_, _, mtr_combined) = calc.mtr(variable_str='e00200p', calc_all_already_called=True) assert np.allclose(mtr_combined, mtr_cmb) assert np.allclose(calc.array('combined'), combinedx) assert np.allclose(calc.array('c00100'), c00100x)
def test_consumption_response(puf_1991, weights_1991): consump = Consumption() mpc = 0.5 consumption_response = {2013: {'_MPC_e20400': [mpc]}} consump.update_consumption(consumption_response) # test incorrect call to response method with pytest.raises(ValueError): consump.response(list(), 1) # test correct call to response method recs = Records(data=puf_1991, weights=weights_1991, start_year=2009) pre = copy.deepcopy(recs.e20400) consump.response(recs, 1.0) post = recs.e20400 actual_diff = post - pre expected_diff = np.ones(recs.dim) * mpc assert np.allclose(actual_diff, expected_diff) # compute earnings mtr with no consumption response recs0 = Records(data=puf_1991, weights=weights_1991, start_year=2009) calc0 = Calculator(policy=Policy(), records=recs0, consumption=None) ided0 = copy.deepcopy(recs0.e20400) (mtr0_ptax, mtr0_itax, _) = calc0.mtr(variable_str='e00200p', wrt_full_compensation=False) assert np.allclose(calc0.records.e20400, ided0) # compute earnings mtr with consumption response recs1 = Records(data=puf_1991, weights=weights_1991, start_year=2009) calc1 = Calculator(policy=Policy(), records=recs1, consumption=None) assert np.allclose(calc1.records.e20400, ided0) calc1.consumption.update_consumption(consumption_response) (mtr1_ptax, mtr1_itax, _) = calc1.mtr(variable_str='e00200p', wrt_full_compensation=False) assert np.allclose(calc1.records.e20400, ided0) # confirm that payroll mtr values are no different assert np.allclose(mtr1_ptax, mtr0_ptax) # confirm that all mtr with cons-resp are no greater than without cons-resp assert np.all(np.less_equal(mtr1_itax, mtr0_itax)) # confirm that some mtr with cons-resp are less than without cons-resp assert np.any(np.less(mtr1_itax, mtr0_itax))
def run(): """ Compute histograms for each marginal tax rate income type using sample input from the 'puf.csv' file and writing output to stdout. """ if NEG_DIFF: sys.stdout.write('MTR computed using NEGATIVE finite_diff.\n') else: sys.stdout.write('MTR computed using POSITIVE finite_diff.\n') # create a Policy object (clp) containing current-law policy parameters clp = Policy() clp.set_year(TAX_YEAR) # create a Records object (puf) containing puf.csv input records puf = Records() recid = puf.RECID # pylint: disable=no-member # create a Calculator object using clp policy and puf records calc = Calculator(policy=clp, records=puf) # . . . specify FICA mtr histogram bin boundaries (or edges): fica_bin_edges = [0.0, 0.02, 0.04, 0.06, 0.08, 0.10, 0.12, 0.14, 0.16, 0.18, 1.0] # the bin boundaries above are arbitrary, so users # may want to experiment with alternative boundaries # . . . specify IIT mtr histogram bin boundaries (or edges): iit_bin_edges = [-1.0, -0.30, -0.20, -0.10, 0.0, 0.10, 0.20, 0.30, 0.40, 0.50, 1.0] # the bin boundaries above are arbitrary, so users # may want to experiment with alternative boundaries assert len(fica_bin_edges) == len(iit_bin_edges) sys.stdout.write('{} = {}\n'.format('Total number of data records', puf.dim)) sys.stdout.write('FICA mtr histogram bin edges:\n') sys.stdout.write(' {}\n'.format(fica_bin_edges)) sys.stdout.write('IIT mtr histogram bin edges:\n') sys.stdout.write(' {}\n'.format(iit_bin_edges)) inctype_header = 'FICA and IIT mtr histogram bin counts for' # compute marginal tax rate (mtr) histograms for each mtr income type for inctype in Calculator.MTR_VALID_INCOME_TYPES: (mtr_fica, mtr_iit, _) = calc.mtr(income_type_str=inctype, negative_finite_diff=NEG_DIFF, wrt_full_compensation=False) sys.stdout.write('{} {}:\n'.format(inctype_header, inctype)) write_mtr_bin_counts(mtr_fica, fica_bin_edges, recid) write_mtr_bin_counts(mtr_iit, iit_bin_edges, recid)
def test_Calculator_using_nonstd_input(rawinputfile): # check Calculator handling of raw, non-standard input data with no aging policy = Policy() policy.set_year(RAWINPUTFILE_YEAR) # set policy params to input data year nonpuf = Records( data=rawinputfile.name, start_year=RAWINPUTFILE_YEAR, # set raw input data year consider_imputations=False) # keeps raw data unchanged assert nonpuf.dim == RAWINPUTFILE_FUNITS calc = Calculator(policy=policy, records=nonpuf, sync_years=False) # keeps raw data unchanged assert calc.current_year == RAWINPUTFILE_YEAR calc.calc_all() exp_iitax = np.zeros((nonpuf.dim, )) assert_allclose(nonpuf._iitax, exp_iitax) mtr_fica, _, _ = calc.mtr(wrt_full_compensation=False) exp_mtr_fica = np.zeros((nonpuf.dim, )) exp_mtr_fica.fill(0.153) assert_allclose(mtr_fica, exp_mtr_fica)
def test_Calculator_using_nonstd_input(rawinputfile): # check Calculator handling of raw, non-standard input data with no aging policy = Policy() policy.set_year(RAWINPUTFILE_YEAR) # set policy params to input data year nonpuf = Records(data=rawinputfile.name, start_year=RAWINPUTFILE_YEAR, # set raw input data year consider_imputations=False) # keeps raw data unchanged assert nonpuf.dim == RAWINPUTFILE_FUNITS calc = Calculator(policy=policy, records=nonpuf, sync_years=False) # keeps raw data unchanged assert calc.current_year == RAWINPUTFILE_YEAR calc.calc_all() exp_iitax = np.zeros((nonpuf.dim,)) assert_array_equal(nonpuf._iitax, exp_iitax) mtr_fica, _, _ = calc.mtr(wrt_full_compensation=False) exp_mtr_fica = np.zeros((nonpuf.dim,)) exp_mtr_fica.fill(0.153) assert_array_equal(mtr_fica, exp_mtr_fica)
def test_Calculator_using_nonstd_input(rawinputfile): # check Calculator handling of raw, non-standard input data with no aging policy = Policy() policy.set_year(RAWINPUTFILE_YEAR) # set policy params to input data year nonpuf = Records(data=rawinputfile.name, blowup_factors=None, # keeps raw data unchanged weights=None, start_year=RAWINPUTFILE_YEAR) # set raw input data year assert nonpuf.dim == RAWINPUTFILE_FUNITS calc = Calculator(policy=policy, records=nonpuf, sync_years=False) # keeps raw data unchanged assert calc.current_year == RAWINPUTFILE_YEAR calc.calc_all() exp_iitax = np.zeros((nonpuf.dim,)) assert np.allclose(nonpuf._iitax, exp_iitax) mtr_ptax, _, _ = calc.mtr(wrt_full_compensation=False) exp_mtr_ptax = np.zeros((nonpuf.dim,)) exp_mtr_ptax.fill(0.153) assert np.allclose(mtr_ptax, exp_mtr_ptax)
def test_calculator_using_nonstd_input(rawinputfile): # check Calculator handling of raw, non-standard input data with no aging pol = Policy() pol.set_year(RAWINPUTFILE_YEAR) # set policy params to input data year nonstd = Records( data=rawinputfile.name, gfactors=None, # keeps raw data unchanged weights=None, start_year=RAWINPUTFILE_YEAR) # set raw input data year assert nonstd.dim == RAWINPUTFILE_FUNITS calc = Calculator(policy=pol, records=nonstd, sync_years=False) # keeps raw data unchanged assert calc.current_year == RAWINPUTFILE_YEAR calc.calc_all() exp_iitax = np.zeros((nonstd.dim, )) assert np.allclose(calc.records.iitax, exp_iitax) mtr_ptax, _, _ = calc.mtr(wrt_full_compensation=False) exp_mtr_ptax = np.zeros((nonstd.dim, )) exp_mtr_ptax.fill(0.153) assert np.allclose(mtr_ptax, exp_mtr_ptax)
def test_calculator_mtr(cps_subsample): rec = Records.cps_constructor(data=cps_subsample) calc = Calculator(policy=Policy(), records=rec) recs_pre_e00200p = copy.deepcopy(calc.records.e00200p) (mtr_ptx, mtr_itx, mtr_combined) = calc.mtr(variable_str='e00200p', zero_out_calculated_vars=True) recs_post_e00200p = copy.deepcopy(calc.records.e00200p) assert np.allclose(recs_post_e00200p, recs_pre_e00200p) assert type(mtr_combined) == np.ndarray assert np.array_equal(mtr_combined, mtr_ptx) is False assert np.array_equal(mtr_ptx, mtr_itx) is False with pytest.raises(ValueError): calc.mtr(variable_str='bad_income_type') (_, _, mtr_combined) = calc.mtr(variable_str='e00200s') assert type(mtr_combined) == np.ndarray (_, _, mtr_combined) = calc.mtr(variable_str='e00650', negative_finite_diff=True) assert type(mtr_combined) == np.ndarray (_, _, mtr_combined) = calc.mtr(variable_str='e00900p') assert type(mtr_combined) == np.ndarray (_, _, mtr_combined) = calc.mtr(variable_str='e01700') assert type(mtr_combined) == np.ndarray (_, _, mtr_combined) = calc.mtr(variable_str='e26270') assert type(mtr_combined) == np.ndarray
def test_Calculator_mtr(records_2009): calc = Calculator(policy=Policy(), records=records_2009) recs_pre_e00200p = copy.deepcopy(calc.records.e00200p) (mtr_ptx, mtr_itx, mtr_combined) = calc.mtr(variable_str='e00200p', zero_out_calculated_vars=True) recs_post_e00200p = copy.deepcopy(calc.records.e00200p) assert np.allclose(recs_post_e00200p, recs_pre_e00200p) assert type(mtr_combined) == np.ndarray assert np.array_equal(mtr_combined, mtr_ptx) is False assert np.array_equal(mtr_ptx, mtr_itx) is False with pytest.raises(ValueError): (_, _, mtr_combined) = calc.mtr(variable_str='bad_income_type') (_, _, mtr_combined) = calc.mtr(variable_str='e00650', negative_finite_diff=True) assert type(mtr_combined) == np.ndarray (_, _, mtr_combined) = calc.mtr(variable_str='e00900p') assert type(mtr_combined) == np.ndarray (_, _, mtr_combined) = calc.mtr(variable_str='e01700') assert type(mtr_combined) == np.ndarray (_, _, mtr_combined) = calc.mtr(variable_str='e26270') assert type(mtr_combined) == np.ndarray
def test_calculator_mtr(pit_fullsample, gst_sample, cit_crosssample): """ Test Calculator mtr method. """ recs = Records(data=pit_fullsample) grecs = GSTRecords(data=gst_sample) crecs = CorpRecords(data=cit_crosssample) calcx = Calculator(policy=Policy(), records=recs, gstrecords=grecs, corprecords=crecs) calcx.calc_all() pitax_x = calcx.array('pitax') GTIx = calcx.array('GTI') calc = Calculator(policy=Policy(), records=recs, gstrecords=grecs, corprecords=crecs) recs_pre_SALARIES = copy.deepcopy(calc.array('SALARIES')) mtr_pitax = calc.mtr(variable_str='SALARIES', zero_out_calculated_vars=True) recs_post_SALARIES = calc.array('SALARIES') assert np.allclose(recs_post_SALARIES, recs_pre_SALARIES) assert np.allclose(calc.array('pitax'), pitax_x) assert np.allclose(calc.array('GTI'), GTIx) with pytest.raises(ValueError): calc.mtr(variable_str='bad_income_type') mtr_pit = calc.mtr(variable_str='SALARIES', calc_all_already_called=True) assert isinstance(mtr_pit, np.ndarray) mtr_pit = calc.mtr(variable_str='PRFT_GAIN_BP_OTHR_SPECLTV_BUS', calc_all_already_called=True) assert isinstance(mtr_pit, np.ndarray) mtr_pit = calc.mtr(variable_str='SALARIES', calc_all_already_called=True) assert np.allclose(mtr_pitax, mtr_pit) assert np.allclose(calc.array('pitax'), pitax_x) assert np.allclose(calc.array('GTI'), GTIx)
def test_mtr(tests_path, puf_path): """ Test Tax-Calculator marginal tax rates with no policy reform using puf.csv Compute histograms for each marginal tax rate income type using sample input from the puf.csv file and writing output to a string, which is then compared for differences with EXPECTED_MTR_RESULTS. """ # pylint: disable=too-many-locals,too-many-statements assert len(PTAX_MTR_BIN_EDGES) == len(ITAX_MTR_BIN_EDGES) # construct actual results string, res res = '' if MTR_NEG_DIFF: res += 'MTR computed using NEGATIVE finite_diff ' else: res += 'MTR computed using POSITIVE finite_diff ' res += 'for tax year {}\n'.format(MTR_TAX_YEAR) # create a Policy object (clp) containing current-law policy parameters clp = Policy() clp.set_year(MTR_TAX_YEAR) # create a Records object (puf) containing puf.csv input records puf = Records(data=puf_path) recid = puf.RECID # pylint: disable=no-member # create a Calculator object using clp policy and puf records calc = Calculator(policy=clp, records=puf) res += '{} = {}\n'.format('Total number of data records', puf.array_length) res += 'PTAX mtr histogram bin edges:\n' res += ' {}\n'.format(PTAX_MTR_BIN_EDGES) res += 'ITAX mtr histogram bin edges:\n' res += ' {}\n'.format(ITAX_MTR_BIN_EDGES) variable_header = 'PTAX and ITAX mtr histogram bin counts for' # compute marginal tax rate (mtr) histograms for each mtr variable for var_str in Calculator.MTR_VALID_VARIABLES: zero_out = (var_str == 'e01400') (mtr_ptax, mtr_itax, _) = calc.mtr(variable_str=var_str, negative_finite_diff=MTR_NEG_DIFF, zero_out_calculated_vars=zero_out, wrt_full_compensation=False) if zero_out: # check that calculated variables are consistent assert np.allclose((calc.array('iitax') + calc.array('payrolltax')), calc.array('combined')) assert np.allclose((calc.array('ptax_was') + calc.array('setax') + calc.array('ptax_amc')), calc.array('payrolltax')) assert np.allclose(calc.array('c21060') - calc.array('c21040'), calc.array('c04470')) assert np.allclose(calc.array('taxbc') + calc.array('c09600'), calc.array('c05800')) assert np.allclose((calc.array('c05800') + calc.array('othertaxes') - calc.array('c07100')), calc.array('c09200')) assert np.allclose(calc.array('c09200') - calc.array('refund'), calc.array('iitax')) if var_str == 'e00200s': # only MARS==2 filing units have valid MTR values mtr_ptax = mtr_ptax[calc.array('MARS') == 2] mtr_itax = mtr_itax[calc.array('MARS') == 2] res += '{} {}:\n'.format(variable_header, var_str) res += mtr_bin_counts(mtr_ptax, PTAX_MTR_BIN_EDGES, recid) res += mtr_bin_counts(mtr_itax, ITAX_MTR_BIN_EDGES, recid) # check for differences between actual and expected results mtrres_path = os.path.join(tests_path, 'pufcsv_mtr_expect.txt') with open(mtrres_path, 'r') as expected_file: txt = expected_file.read() expected_results = txt.rstrip('\n\t ') + '\n' # cleanup end of file txt if nonsmall_diffs(res.splitlines(True), expected_results.splitlines(True)): new_filename = '{}{}'.format(mtrres_path[:-10], 'actual.txt') with open(new_filename, 'w') as new_file: new_file.write(res) msg = 'PUFCSV MTR RESULTS DIFFER\n' msg += '-------------------------------------------------\n' msg += '--- NEW RESULTS IN pufcsv_mtr_actual.txt FILE ---\n' msg += '--- if new OK, copy pufcsv_mtr_actual.txt to ---\n' msg += '--- pufcsv_mtr_expect.txt ---\n' msg += '--- and rerun test. ---\n' msg += '-------------------------------------------------\n' raise ValueError(msg)
def test_mtr(tests_path, puf_path): """ Test Tax-Calculator marginal tax rates with no policy reform using puf.csv Compute histograms for each marginal tax rate income type using sample input from the puf.csv file and writing output to a string, which is then compared for differences with EXPECTED_MTR_RESULTS. """ # pylint: disable=too-many-locals # for fixture args, pylint: disable=redefined-outer-name assert len(PTAX_MTR_BIN_EDGES) == len(ITAX_MTR_BIN_EDGES) # construct actual results string, res res = '' if MTR_NEG_DIFF: res += 'MTR computed using NEGATIVE finite_diff ' else: res += 'MTR computed using POSITIVE finite_diff ' res += 'for tax year {}\n'.format(MTR_TAX_YEAR) # create a Policy object (clp) containing current-law policy parameters clp = Policy() clp.set_year(MTR_TAX_YEAR) # create a Records object (puf) containing puf.csv input records puf = Records(data=puf_path) recid = puf.RECID # pylint: disable=no-member # create a Calculator object using clp policy and puf records calc = Calculator(policy=clp, records=puf) res += '{} = {}\n'.format('Total number of data records', puf.dim) res += 'PTAX mtr histogram bin edges:\n' res += ' {}\n'.format(PTAX_MTR_BIN_EDGES) res += 'ITAX mtr histogram bin edges:\n' res += ' {}\n'.format(ITAX_MTR_BIN_EDGES) variable_header = 'PTAX and ITAX mtr histogram bin counts for' # compute marginal tax rate (mtr) histograms for each mtr variable for var_str in Calculator.MTR_VALID_VARIABLES: zero_out = (var_str == 'e01400') (mtr_ptax, mtr_itax, _) = calc.mtr(variable_str=var_str, negative_finite_diff=MTR_NEG_DIFF, zero_out_calculated_vars=zero_out, wrt_full_compensation=False) res += '{} {}:\n'.format(variable_header, var_str) res += mtr_bin_counts(mtr_ptax, PTAX_MTR_BIN_EDGES, recid) res += mtr_bin_counts(mtr_itax, ITAX_MTR_BIN_EDGES, recid) # generate differences between actual and expected results actual = res.splitlines(True) mtrres_path = os.path.join(tests_path, 'pufcsv_mtr_expect.txt') with open(mtrres_path, 'r') as expected_file: txt = expected_file.read() expected_results = txt.rstrip('\n\t ') + '\n' # cleanup end of file txt expected = expected_results.splitlines(True) diff = difflib.unified_diff(expected, actual, fromfile='expected', tofile='actual', n=0) # convert diff generator into a list of lines: diff_lines = list() for line in diff: diff_lines.append(line) # test failure if there are any diff_lines if len(diff_lines) > 0: new_filename = '{}{}'.format(mtrres_path[:-10], 'actual.txt') with open(new_filename, 'w') as new_file: new_file.write(res) msg = 'PUFCSV MTR RESULTS DIFFER\n' msg += '-------------------------------------------------\n' msg += '--- NEW RESULTS IN pufcsv_mtr_actual.txt FILE ---\n' msg += '--- if new OK, copy pufcsv_mtr_actual.txt to ---\n' msg += '--- pufcsv_mtr_expect.txt ---\n' msg += '--- and rerun test. ---\n' msg += '-------------------------------------------------\n' raise ValueError(msg)
def test_mtr(): """ Test Tax-Calculator marginal tax rates with no policy reform using puf.csv Compute histograms for each marginal tax rate income type using sample input from the puf.csv file and writing output to a string, which is then compared for differences with EXPECTED_MTR_RESULTS. """ # pylint: disable=too-many-locals assert len(FICA_MTR_BIN_EDGES) == len(IIT_MTR_BIN_EDGES) # construct actual results string, res res = '' if MTR_NEG_DIFF: res += 'MTR computed using NEGATIVE finite_diff ' else: res += 'MTR computed using POSITIVE finite_diff ' res += 'for tax year {}\n'.format(MTR_TAX_YEAR) # create a Policy object (clp) containing current-law policy parameters clp = Policy() clp.set_year(MTR_TAX_YEAR) # create a Records object (puf) containing puf.csv input records puf = Records(data=PUFCSV_PATH) recid = puf.RECID # pylint: disable=no-member # create a Calculator object using clp policy and puf records calc = Calculator(policy=clp, records=puf) res += '{} = {}\n'.format('Total number of data records', puf.dim) res += 'FICA mtr histogram bin edges:\n' res += ' {}\n'.format(FICA_MTR_BIN_EDGES) res += 'IIT mtr histogram bin edges:\n' res += ' {}\n'.format(IIT_MTR_BIN_EDGES) inctype_header = 'FICA and IIT mtr histogram bin counts for' # compute marginal tax rate (mtr) histograms for each mtr income type for inctype in Calculator.MTR_VALID_INCOME_TYPES: (mtr_fica, mtr_iit, _) = calc.mtr(income_type_str=inctype, negative_finite_diff=MTR_NEG_DIFF, wrt_full_compensation=False) res += '{} {}:\n'.format(inctype_header, inctype) res += mtr_bin_counts(mtr_fica, FICA_MTR_BIN_EDGES, recid) res += mtr_bin_counts(mtr_iit, IIT_MTR_BIN_EDGES, recid) # generate differences between actual and expected results actual = res.splitlines(True) with open(MTRRES_PATH, 'r') as expected_file: txt = expected_file.read() expected_results = txt.rstrip('\n\t ') + '\n' # cleanup end of file txt expected = expected_results.splitlines(True) diff = difflib.unified_diff(expected, actual, fromfile='expected', tofile='actual', n=0) # convert diff generator into a list of lines: diff_lines = list() for line in diff: diff_lines.append(line) # test failure if there are any diff_lines if len(diff_lines) > 0: new_filename = '{}{}'.format(MTRRES_PATH[:-10], 'actual.txt') with open(new_filename, 'w') as new_file: new_file.write(res) sys.stdout.write('*************************************************\n') sys.stdout.write('*** NEW RESULTS IN pufcsv_mtr_actual.txt FILE ***\n') sys.stdout.write('*** if new OK, copy pufcsv_mtr_actual.txt to ***\n') sys.stdout.write('*** pufcsv_mtr_expect.txt ***\n') sys.stdout.write('*** and rerun test. ***\n') sys.stdout.write('*************************************************\n') assert False
def main(mpc_e17500, mpc_e18400, mpc_e19800, mpc_e20400): """ Highest-level logic of consumption.py script that produces Tax-Calculator marginal-tax-rate results running the taxcalc package on this computer. """ # pylint: disable=too-many-locals # pylint: disable=too-many-statements if not os.path.isfile(PUFCSV_PATH): sys.stderr.write('ERROR: file {} does not exist\n'.format(PUFCSV_PATH)) return 1 cyr = 2014 # compute mtr under current-law policy with no consumption response recs0 = Records(data=PUFCSV_PATH) calc0 = Calculator(policy=Policy(), records=recs0, consumption=None, verbose=False) calc0.advance_to_year(cyr) wghts = calc0.records.s006 (mtr0_fica, mtr0_itax, _) = calc0.mtr(income_type_str='e00200p', wrt_full_compensation=False) # compute mtr under current-law policy with specified consumption response consump = Consumption() consump_mpc = {cyr: {'_MPC_e17500': [mpc_e17500], '_MPC_e18400': [mpc_e18400], '_MPC_e19800': [mpc_e19800], '_MPC_e20400': [mpc_e20400]}} consump.update_consumption(consump_mpc) recs1 = Records(data=PUFCSV_PATH) calc1 = Calculator(policy=Policy(), records=recs1, consumption=consump, verbose=False) calc1.advance_to_year(cyr) assert calc1.consumption.current_year == cyr (mtr1_fica, mtr1_itax, _) = calc1.mtr(income_type_str='e00200p', wrt_full_compensation=False) # compare unweighted mtr results with and without consumption response epsilon = 1.0e-6 # this would represent a mtr of 0.0001 percent assert np.allclose(mtr1_fica, mtr0_fica, atol=epsilon, rtol=0.0) mtr_raw_diff = mtr1_itax - mtr0_itax mtr1_itax = np.where(np.logical_and(mtr_raw_diff > 0.0, mtr_raw_diff < epsilon), mtr0_itax, mtr1_itax) # zero out small positive diffs num_total = mtr1_itax.size num_increases = np.sum(np.greater(mtr1_itax, mtr0_itax)) num_decreases = np.sum(np.less(mtr1_itax, mtr0_itax)) num_nochanges = num_total - num_increases - num_decreases res = 'unweighted_num_of_mtr_{}_with_consump_response= {:6d} ({:5.1f}%)\n' sys.stdout.write(res.format('increases', num_increases, (100.0 * num_increases) / num_total)) sys.stdout.write(res.format('decreases', num_decreases, (100.0 * num_decreases) / num_total)) sys.stdout.write(res.format('nochanges', num_nochanges, (100.0 * num_nochanges) / num_total)) sys.stdout.write(res.format('all_units', num_total, 100.0)) # compute average size of decreases in mtr_itax mtr_pre = mtr0_itax[mtr1_itax < mtr0_itax] assert mtr_pre.size == num_decreases avg_pre = np.mean(mtr_pre) res = 'unweighted_abs_mean_no_c_resp(for_decreases)mtr_itax= {:.4f}\n' sys.stdout.write(res.format(avg_pre)) mtr_diff = mtr1_itax - mtr0_itax mtr_neg = mtr_diff[mtr_diff < 0.0] assert mtr_neg.size == num_decreases avg_neg = np.mean(mtr_neg) assert avg_neg < 0.0 res = 'unweighted_abs_mean_change(for_decreases)in_mtr_itax= {:.4f}\n' sys.stdout.write(res.format(-avg_neg)) res = ' ratio_of_abs_change_in_mtr_itax_and_no_c_resp_mtr_itax= {:.3f}\n' sys.stdout.write(res.format(-avg_neg / avg_pre)) # compare weighted mtr results with and without consumption response wghts_pre = wghts[mtr1_itax < mtr0_itax] assert wghts_pre.size == num_decreases res = 'weighted_percent_of_units_with_mtr_decrease= {:.1f}%\n' frac = wghts_pre.sum() / wghts.sum() sys.stdout.write(res.format(100.0 * frac)) res = ' ratio_of_abs_change_in_mtr_itax_and_no_c_resp_mtr_itax= {:.3f}\n' w_avg_pre = np.mean((mtr_pre * wghts_pre).sum() / wghts_pre.sum()) w_avg_neg = np.mean((mtr_neg * wghts_pre).sum() / wghts_pre.sum()) sys.stdout.write(res.format(-w_avg_neg / w_avg_pre)) # return no-error exit code return 0
def main(mpc_e17500, mpc_e18400, mpc_e19800, mpc_e20400): """ Highest-level logic of consumption.py script that produces Tax-Calculator marginal-tax-rate results running the taxcalc package on this computer. """ # pylint: disable=too-many-locals # pylint: disable=too-many-statements if not os.path.isfile(PUFCSV_PATH): sys.stderr.write('ERROR: file {} does not exist\n'.format(PUFCSV_PATH)) return 1 cyr = 2014 # compute mtr under current-law policy with no consumption response recs0 = Records(data=PUFCSV_PATH) calc0 = Calculator(policy=Policy(), records=recs0, consumption=None, verbose=False) calc0.advance_to_year(cyr) wghts = calc0.records.s006 (mtr0_ptax, mtr0_itax, _) = calc0.mtr(variable_str='e00200p', wrt_full_compensation=False) # compute mtr under current-law policy with specified consumption response consump = Consumption() consump_mpc = { cyr: { '_MPC_e17500': [mpc_e17500], '_MPC_e18400': [mpc_e18400], '_MPC_e19800': [mpc_e19800], '_MPC_e20400': [mpc_e20400] } } consump.update_consumption(consump_mpc) recs1 = Records(data=PUFCSV_PATH) calc1 = Calculator(policy=Policy(), records=recs1, consumption=consump, verbose=False) calc1.advance_to_year(cyr) assert calc1.consumption.current_year == cyr (mtr1_ptax, mtr1_itax, _) = calc1.mtr(variable_str='e00200p', wrt_full_compensation=False) # compare unweighted mtr results with and without consumption response epsilon = 1.0e-6 # this would represent a mtr of 0.0001 percent assert np.allclose(mtr1_ptax, mtr0_ptax, atol=epsilon, rtol=0.0) mtr_raw_diff = mtr1_itax - mtr0_itax mtr1_itax = np.where( np.logical_and(mtr_raw_diff > 0.0, mtr_raw_diff < epsilon), mtr0_itax, mtr1_itax) # zero out small positive diffs num_total = mtr1_itax.size num_increases = np.sum(np.greater(mtr1_itax, mtr0_itax)) num_decreases = np.sum(np.less(mtr1_itax, mtr0_itax)) num_nochanges = num_total - num_increases - num_decreases res = 'unweighted_num_of_mtr_{}_with_consump_response= {:6d} ({:5.1f}%)\n' sys.stdout.write( res.format('increases', num_increases, (100.0 * num_increases) / num_total)) sys.stdout.write( res.format('decreases', num_decreases, (100.0 * num_decreases) / num_total)) sys.stdout.write( res.format('nochanges', num_nochanges, (100.0 * num_nochanges) / num_total)) sys.stdout.write(res.format('all_units', num_total, 100.0)) # compute average size of decreases in mtr_itax mtr_pre = mtr0_itax[mtr1_itax < mtr0_itax] assert mtr_pre.size == num_decreases avg_pre = np.mean(mtr_pre) res = 'unweighted_abs_mean_no_c_resp(for_decreases)mtr_itax= {:.4f}\n' sys.stdout.write(res.format(avg_pre)) mtr_diff = mtr1_itax - mtr0_itax mtr_neg = mtr_diff[mtr_diff < 0.0] assert mtr_neg.size == num_decreases avg_neg = np.mean(mtr_neg) assert avg_neg < 0.0 res = 'unweighted_abs_mean_change(for_decreases)in_mtr_itax= {:.4f}\n' sys.stdout.write(res.format(-avg_neg)) res = ' ratio_of_abs_change_in_mtr_itax_and_no_c_resp_mtr_itax= {:.3f}\n' sys.stdout.write(res.format(-avg_neg / avg_pre)) # compare weighted mtr results with and without consumption response wghts_pre = wghts[mtr1_itax < mtr0_itax] assert wghts_pre.size == num_decreases res = 'weighted_percent_of_units_with_mtr_decrease= {:.1f}%\n' frac = wghts_pre.sum() / wghts.sum() sys.stdout.write(res.format(100.0 * frac)) res = ' ratio_of_abs_change_in_mtr_itax_and_no_c_resp_mtr_itax= {:.3f}\n' w_avg_pre = np.mean((mtr_pre * wghts_pre).sum() / wghts_pre.sum()) w_avg_neg = np.mean((mtr_neg * wghts_pre).sum() / wghts_pre.sum()) sys.stdout.write(res.format(-w_avg_neg / w_avg_pre)) # return no-error exit code return 0
def test_mtr(): """ Test Tax-Calculator marginal tax rates with no policy reform using puf.csv Compute histograms for each marginal tax rate income type using sample input from the puf.csv file and writing output to a string, which is then compared for differences with EXPECTED_MTR_RESULTS. """ # pylint: disable=too-many-locals assert len(FICA_MTR_BIN_EDGES) == len(IIT_MTR_BIN_EDGES) # construct actual results string, res res = '' if MTR_NEG_DIFF: res += 'MTR computed using NEGATIVE finite_diff.\n' else: res += 'MTR computed using POSITIVE finite_diff.\n' # create a Policy object (clp) containing current-law policy parameters clp = Policy() clp.set_year(MTR_TAX_YEAR) # create a Records object (puf) containing puf.csv input records puf = Records(data=PUFCSV_PATH) recid = puf.RECID # pylint: disable=no-member # create a Calculator object using clp policy and puf records calc = Calculator(policy=clp, records=puf) res += '{} = {}\n'.format('Total number of data records', puf.dim) res += 'FICA mtr histogram bin edges:\n' res += ' {}\n'.format(FICA_MTR_BIN_EDGES) res += 'IIT mtr histogram bin edges:\n' res += ' {}\n'.format(IIT_MTR_BIN_EDGES) inctype_header = 'FICA and IIT mtr histogram bin counts for' # compute marginal tax rate (mtr) histograms for each mtr income type for inctype in Calculator.MTR_VALID_INCOME_TYPES: (mtr_fica, mtr_iit, _) = calc.mtr(income_type_str=inctype, negative_finite_diff=MTR_NEG_DIFF, wrt_full_compensation=False) res += '{} {}:\n'.format(inctype_header, inctype) res += mtr_bin_counts(mtr_fica, FICA_MTR_BIN_EDGES, recid) res += mtr_bin_counts(mtr_iit, IIT_MTR_BIN_EDGES, recid) # generate differences between actual and expected results actual = res.splitlines(True) with open(MTRRES_PATH, 'r') as expected_file: txt = expected_file.read() expected_results = txt.rstrip('\n\t ') + '\n' # cleanup end of file txt expected = expected_results.splitlines(True) diff = difflib.unified_diff(expected, actual, fromfile='expected', tofile='actual', n=0) # convert diff generator into a list of lines: diff_lines = list() for line in diff: diff_lines.append(line) # test failure if there are any diff_lines if len(diff_lines) > 0: new_filename = '{}{}'.format(MTRRES_PATH[:-10], 'actual.txt') with open(new_filename, 'w') as new_file: new_file.write(res) sys.stdout.write('*************************************************\n') sys.stdout.write('*** NEW RESULTS IN pufcsv_mtr_actual.txt FILE ***\n') sys.stdout.write('*** if new OK, copy pufcsv_mtr_actual.txt to ***\n') sys.stdout.write('*** pufcsv_mtr_expect.txt ***\n') sys.stdout.write('*** and rerun test. ***\n') sys.stdout.write('*************************************************\n') assert False
def run_nth_year_mtr_calc(year_n, start_year, tax_dta, user_mods="", return_json=True): #Only makes sense to run for budget years 1 through n-1 (not for year 0) assert year_n > 0 elasticity_gdp = elasticity_of_gdp_year_n(user_mods, year_n) ######################################################################### # Create Calculators and Masks ######################################################################### records = Records(tax_dta.copy(deep=True)) records3 = Records(tax_dta.copy(deep=True)) # Default Plans # Create a default Policy object params = Policy(start_year=2013) # Create a Calculator calc1 = Calculator(policy=params, records=records) growth_assumptions = only_growth_assumptions(user_mods, start_year) if growth_assumptions: calc1.growth.update_economic_growth(growth_assumptions) while calc1.current_year < start_year: calc1.increment_year() assert calc1.current_year == start_year # User specified Plans reform_mods = only_reform_mods(user_mods, start_year) params3 = Policy(start_year=2013) params3.implement_reform(reform_mods) behavior3 = Behavior(start_year=2013) # Create a Calculator for the user specified plan calc3 = Calculator(policy=params3, records=records3, behavior=behavior3) if growth_assumptions: calc3.growth.update_economic_growth(growth_assumptions) while calc3.current_year < start_year: calc3.increment_year() assert calc3.current_year == start_year # Get a random seed based on user specified plan seed = random_seed_from_plan(calc3) np.random.seed(seed) for i in range(0, year_n-1): calc1.increment_year() calc3.increment_year() calc1.calc_all() calc3.calc_all() mtr_fica_x, mtr_iit_x, mtr_combined_x = calc1.mtr() mtr_fica_y, mtr_iit_y, mtr_combined_y = calc3.mtr() #Assert that the current year is one behind the year we are calculating assert (calc1.current_year + 1) == (start_year + year_n) assert (calc3.current_year + 1) == (start_year + year_n) after_tax_mtr_x = 1 - ((mtr_combined_x * calc1.records.c00100 * calc1.records.s006).sum()/ (calc1.records.c00100 * calc1.records.s006).sum()) after_tax_mtr_y = 1 - ((mtr_combined_y * calc3.records.c00100 * calc3.records.s006).sum()/ (calc3.records.c00100 * calc3.records.s006).sum()) diff_avg_mtr_combined_y = after_tax_mtr_y - after_tax_mtr_x percent_diff_mtr = diff_avg_mtr_combined_y / after_tax_mtr_x gdp_effect_y = percent_diff_mtr * elasticity_gdp gdp_df = pd.DataFrame(data=[gdp_effect_y], columns=["col0"]) if not return_json: return gdp_effect_y gdp_elast_names_i = [x+'_'+str(year_n) for x in GDP_elasticity_row_names] gdp_elast_total = create_json_table(gdp_df, row_names=gdp_elast_names_i, num_decimals=5) # Make the one-item lists of strings just strings gdp_elast_total = dict((k, v[0]) for k,v in gdp_elast_total.items()) return gdp_elast_total
def test_cg_top_rate(): """ Test top CG bracket and rate. """ cy = 2019 # set NIIT and STD to zero to isolate CG tax rates base = {"NIIT_rt": {2019: 0}, "STD": {2019: [0, 0, 0, 0, 0]}} # create additional top CG bracket and rate ref = { "CG_brk3": { 2019: [1000000, 1000000, 1000000, 1000000, 1000000] }, "CG_rt4": { 2019: 0.4 }, "NIIT_rt": { 2019: 0 }, "STD": { 2019: [0, 0, 0, 0, 0] } } # create one record just below the top CG bracket and one just above VARS = 'RECID,MARS,p23250\n' FUNITS = '1,2,999999\n2,2,1000001\n' pol_base = Policy() pol_base.implement_reform(base) pol_ref = Policy() pol_ref.implement_reform(ref) funit_df = pd.read_csv(StringIO(VARS + FUNITS)) recs = Records(data=funit_df, start_year=cy, gfactors=None, weights=None) calc_base = Calculator(policy=pol_base, records=recs) calc_base.calc_all() calc_ref = Calculator(policy=pol_ref, records=recs) calc_ref.calc_all() # calculate MTRs wrt long term gains mtr_base = calc_base.mtr(variable_str='p23250', calc_all_already_called=True, wrt_full_compensation=False) mtr_itax_base = mtr_base[1] cg_rt3 = pol_base.to_array('CG_rt3', year=2019) # check that MTR for both records is equal to CG_rt3 assert np.allclose(mtr_itax_base, cg_rt3) # calculate MTRs under reform mtr_ref = calc_ref.mtr(variable_str='p23250', calc_all_already_called=True, wrt_full_compensation=False) mtr_itax_ref = mtr_ref[1] cg_rt3_ref = pol_ref.to_array('CG_rt3', year=2019) cg_rt4_ref = pol_ref.to_array(param='CG_rt4', year=2019) # check that MTR of houshold below top threshold is equal to # CG_rt3 assert np.allclose(mtr_itax_ref[0], cg_rt3_ref) # check that MTR of household above top threshold is equal to # CG_rt4 assert np.allclose(mtr_itax_ref[1], cg_rt4_ref)