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)
Exemple #2
0
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
Exemple #12
0
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
Exemple #14
0
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))
Exemple #19
0
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)
Exemple #21
0
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
Exemple #26
0
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)
Exemple #27
0
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
Exemple #32
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 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)
Exemple #34
0
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
Exemple #35
0
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)
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)