def __init__(self, input_filename, reform, exact_calculations, emulate_taxsim_2441_logic, output_records): """ SimpleTaxIO class constructor. """ # pylint: disable=too-many-arguments # check that input_filename is a string if not isinstance(input_filename, six.string_types): msg = 'SimpleTaxIO.ctor input_filename is not a string' raise ValueError(msg) # construct output_filename and delete old output file if it exists # ... construct reform extension to output_filename if reform is None: ref = '' self._using_reform_file = True else: # if reform is not None if isinstance(reform, six.string_types): if reform.endswith('.json'): ref = '-{}'.format(reform[:-5]) else: ref = '-{}'.format(reform) self._using_reform_file = True elif isinstance(reform, dict): ref = '' self._using_reform_file = False else: msg = 'SimpleTaxIO.ctor reform is neither None, str, nor dict' raise ValueError(msg) # ... construct whole output_filename self._using_input_file = True self._output_filename = '{}.out-simtax{}'.format(input_filename, ref) if os.path.isfile(self._output_filename): os.remove(self._output_filename) # pragma: no cover # check for existence of file named input_filename if not os.path.isfile(input_filename): msg = 'INPUT file named {} could not be found' raise ValueError(msg.format(input_filename)) # read input file contents into self._input dictionary self._read_input(input_filename) self.policy = Policy() # implement reform if reform is specified if reform: if self._using_reform_file: param_dict = Calculator.read_json_param_objects(reform, None) r_pol = param_dict['policy'] else: r_pol = reform self.policy.implement_reform(r_pol) # validate input variable values self._validate_input() self.calc = self._calc_object(exact_calculations, emulate_taxsim_2441_logic, output_records)
def init(self, input_data, tax_year, reform, assump, growdiff_response, aging_input_data, exact_calculations): """ TaxCalcIO class post-constructor method that completes initialization. Parameters ---------- First four parameters are same as for TaxCalcIO constructor: input_data, tax_year, reform, assump. growdiff_response: Growdiff object or None growdiff_response Growdiff object is used only by the TaxCalcIO.growmodel_analysis method; must be None in all other cases. aging_input_data: boolean whether or not to extrapolate Records data from data year to tax_year. exact_calculations: boolean specifies whether or not exact tax calculations are done without any smoothing of "stair-step" provisions in the tax law. """ # pylint: disable=too-many-arguments,too-many-locals # pylint: disable=too-many-statements,too-many-branches self.errmsg = '' # get parameter dictionaries from --reform and --assump files paramdict = Calculator.read_json_param_objects(reform, assump) # create Behavior object beh = Behavior() beh.update_behavior(paramdict['behavior']) self.behavior_has_any_response = beh.has_any_response() # create gdiff_baseline object gdiff_baseline = Growdiff() gdiff_baseline.update_growdiff(paramdict['growdiff_baseline']) # create Growfactors clp object that incorporates gdiff_baseline gfactors_clp = Growfactors() gdiff_baseline.apply_to(gfactors_clp) # specify gdiff_response object if growdiff_response is None: gdiff_response = Growdiff() gdiff_response.update_growdiff(paramdict['growdiff_response']) elif isinstance(growdiff_response, Growdiff): gdiff_response = growdiff_response else: gdiff_response = None msg = 'TaxCalcIO.more_init: growdiff_response is neither None ' msg += 'nor a Growdiff object' self.errmsg += 'ERROR: {}\n'.format(msg) if gdiff_response is not None: some_gdiff_response = gdiff_response.has_any_response() if self.behavior_has_any_response and some_gdiff_response: msg = 'ASSUMP file cannot specify any "behavior" when using ' msg += 'GrowModel or when ASSUMP file has "growdiff_response"' self.errmsg += 'ERROR: {}\n'.format(msg) # create Growfactors ref object that has both gdiff objects applied gfactors_ref = Growfactors() gdiff_baseline.apply_to(gfactors_ref) if gdiff_response is not None: gdiff_response.apply_to(gfactors_ref) # create Policy objects if self.specified_reform: pol = Policy(gfactors=gfactors_ref) try: pol.implement_reform(paramdict['policy']) self.errmsg += pol.reform_errors except ValueError as valerr_msg: self.errmsg += valerr_msg.__str__() else: pol = Policy(gfactors=gfactors_clp) clp = Policy(gfactors=gfactors_clp) # check for valid tax_year value if tax_year < pol.start_year: msg = 'tax_year {} less than policy.start_year {}' msg = msg.format(tax_year, pol.start_year) self.errmsg += 'ERROR: {}\n'.format(msg) if tax_year > pol.end_year: msg = 'tax_year {} greater than policy.end_year {}' msg = msg.format(tax_year, pol.end_year) self.errmsg += 'ERROR: {}\n'.format(msg) # any errors imply cannot proceed with calculations if self.errmsg: return # set policy to tax_year pol.set_year(tax_year) clp.set_year(tax_year) # read input file contents into Records objects if aging_input_data: if self.cps_input_data: recs = Records.cps_constructor( gfactors=gfactors_ref, exact_calculations=exact_calculations) recs_clp = Records.cps_constructor( gfactors=gfactors_clp, exact_calculations=exact_calculations) else: # if not cps_input_data recs = Records(data=input_data, gfactors=gfactors_ref, exact_calculations=exact_calculations) recs_clp = Records(data=input_data, gfactors=gfactors_clp, exact_calculations=exact_calculations) else: # input_data are raw data that are not being aged recs = Records(data=input_data, gfactors=None, exact_calculations=exact_calculations, weights=None, adjust_ratios=None, start_year=tax_year) recs_clp = copy.deepcopy(recs) if tax_year < recs.data_year: msg = 'tax_year {} less than records.data_year {}' msg = msg.format(tax_year, recs.data_year) self.errmsg += 'ERROR: {}\n'.format(msg) # create Calculator objects con = Consumption() con.update_consumption(paramdict['consumption']) self.calc = Calculator(policy=pol, records=recs, verbose=True, consumption=con, behavior=beh, sync_years=aging_input_data) self.calc_clp = Calculator(policy=clp, records=recs_clp, verbose=False, consumption=con, sync_years=aging_input_data) # remember parameter dictionary for reform documentation self.param_dict = paramdict
def init(self, input_data, tax_year, baseline, reform, assump, growdiff_growmodel, aging_input_data, exact_calculations): """ TaxCalcIO class post-constructor method that completes initialization. Parameters ---------- First five are same as the first five of the TaxCalcIO constructor: input_data, tax_year, baseline, reform, assump. growdiff_growmodel: GrowDiff object or None growdiff_growmodel GrowDiff object is used only in the TaxCalcIO.growmodel_analysis method. aging_input_data: boolean whether or not to extrapolate Records data from data year to tax_year. exact_calculations: boolean specifies whether or not exact tax calculations are done without any smoothing of "stair-step" provisions in the tax law. """ # pylint: disable=too-many-arguments,too-many-locals # pylint: disable=too-many-statements,too-many-branches self.errmsg = '' # get policy parameter dictionary from --baseline file basedict = Calculator.read_json_param_objects(baseline, None) # get assumption sub-dictionaries paramdict = Calculator.read_json_param_objects(None, assump) # get policy parameter dictionaries from --reform file(s) policydicts = list() if self.specified_reform: reforms = reform.split('+') for ref in reforms: pdict = Calculator.read_json_param_objects(ref, None) policydicts.append(pdict['policy']) paramdict['policy'] = policydicts[0] # remember parameters for reform documentation self.param_dict = paramdict self.policy_dicts = policydicts # create Behavior object beh = Behavior() try: beh.update_behavior(paramdict['behavior']) except ValueError as valerr_msg: self.errmsg += valerr_msg.__str__() self.behavior_has_any_response = beh.has_any_response() # create gdiff_baseline object gdiff_baseline = GrowDiff() try: gdiff_baseline.update_growdiff(paramdict['growdiff_baseline']) except ValueError as valerr_msg: self.errmsg += valerr_msg.__str__() # create GrowFactors base object that incorporates gdiff_baseline gfactors_base = GrowFactors() gdiff_baseline.apply_to(gfactors_base) # specify gdiff_response object gdiff_response = GrowDiff() try: gdiff_response.update_growdiff(paramdict['growdiff_response']) except ValueError as valerr_msg: self.errmsg += valerr_msg.__str__() # create GrowFactors ref object that has all gdiff objects applied gfactors_ref = GrowFactors() gdiff_baseline.apply_to(gfactors_ref) gdiff_response.apply_to(gfactors_ref) if growdiff_growmodel: growdiff_growmodel.apply_to(gfactors_ref) # create Policy objects: # ... the baseline Policy object base = Policy(gfactors=gfactors_base) try: base.implement_reform(basedict['policy'], print_warnings=False, raise_errors=False) self.errmsg += base.parameter_errors except ValueError as valerr_msg: self.errmsg += valerr_msg.__str__() # ... the reform Policy object if self.specified_reform: pol = Policy(gfactors=gfactors_ref) for poldict in policydicts: try: pol.implement_reform(poldict, print_warnings=False, raise_errors=False) self.errmsg += pol.parameter_errors except ValueError as valerr_msg: self.errmsg += valerr_msg.__str__() else: pol = Policy(gfactors=gfactors_base) # create Consumption object con = Consumption() try: con.update_consumption(paramdict['consumption']) except ValueError as valerr_msg: self.errmsg += valerr_msg.__str__() # create GrowModel object self.growmodel = GrowModel() try: self.growmodel.update_growmodel(paramdict['growmodel']) except ValueError as valerr_msg: self.errmsg += valerr_msg.__str__() # check for valid tax_year value if tax_year < pol.start_year: msg = 'tax_year {} less than policy.start_year {}' msg = msg.format(tax_year, pol.start_year) self.errmsg += 'ERROR: {}\n'.format(msg) if tax_year > pol.end_year: msg = 'tax_year {} greater than policy.end_year {}' msg = msg.format(tax_year, pol.end_year) self.errmsg += 'ERROR: {}\n'.format(msg) # any errors imply cannot proceed with calculations if self.errmsg: return # set policy to tax_year pol.set_year(tax_year) base.set_year(tax_year) # read input file contents into Records objects if aging_input_data: if self.cps_input_data: recs = Records.cps_constructor( gfactors=gfactors_ref, exact_calculations=exact_calculations) recs_base = Records.cps_constructor( gfactors=gfactors_base, exact_calculations=exact_calculations) else: # if not cps_input_data but aging_input_data recs = Records(data=input_data, gfactors=gfactors_ref, exact_calculations=exact_calculations) recs_base = Records(data=input_data, gfactors=gfactors_base, exact_calculations=exact_calculations) else: # input_data are raw data that are not being aged recs = Records(data=input_data, gfactors=None, exact_calculations=exact_calculations, weights=None, adjust_ratios=None, start_year=tax_year) recs_base = copy.deepcopy(recs) if tax_year < recs.data_year: msg = 'tax_year {} less than records.data_year {}' msg = msg.format(tax_year, recs.data_year) self.errmsg += 'ERROR: {}\n'.format(msg) # create Calculator objects self.calc = Calculator(policy=pol, records=recs, verbose=True, consumption=con, behavior=beh, sync_years=aging_input_data) self.calc_base = Calculator(policy=base, records=recs_base, verbose=False, consumption=con, sync_years=aging_input_data)