def setUpTestData(cls): cls.project = Project.objects.create() make_cdc_units_and_targets(cls.project) cls.forecast_model = ForecastModel.objects.create( project=cls.project, name='name', abbreviation='abbrev') time_zero = TimeZero.objects.create( project=cls.project, timezero_date=(pymmwr.mmwr_week_to_date(2017, 1))) csv_file_path = Path( 'forecast_app/tests/model_error/ensemble/EW1-KoTstable-2017-01-17.csv' ) # EW01 2017 cls.forecast1 = load_cdc_csv_forecast_file(2016, cls.forecast_model, csv_file_path, time_zero) time_zero = TimeZero.objects.create( project=cls.project, timezero_date=(pymmwr.mmwr_week_to_date(2017, 2))) csv_file_path = Path( 'forecast_app/tests/model_error/ensemble/EW2-KoTstable-2017-01-23.csv' ) # EW02 2017 cls.forecast2 = load_cdc_csv_forecast_file(2016, cls.forecast_model, csv_file_path, time_zero) time_zero = TimeZero.objects.create( project=cls.project, timezero_date=(pymmwr.mmwr_week_to_date(2016, 51))) csv_file_path = Path( 'forecast_app/tests/model_error/ensemble/EW51-KoTstable-2017-01-03.csv' ) # EW51 2016 cls.forecast3 = load_cdc_csv_forecast_file(2016, cls.forecast_model, csv_file_path, time_zero) time_zero = TimeZero.objects.create( project=cls.project, timezero_date=(pymmwr.mmwr_week_to_date(2016, 52))) csv_file_path = Path( 'forecast_app/tests/model_error/ensemble/EW52-KoTstable-2017-01-09.csv' ) # EW52 2016 cls.forecast4 = load_cdc_csv_forecast_file(2016, cls.forecast_model, csv_file_path, time_zero) # 'mini' season for testing. from: # model_error_calculations.txt -> model_error_calculations.py -> model_error_calculations.xlsx: cls.exp_target_to_mae = { '1 wk ahead': 0.215904853, '2 wk ahead': 0.458186984, '3 wk ahead': 0.950515864, '4 wk ahead': 1.482010693 } load_truth_data( cls.project, Path('forecast_app/tests/truth_data/mean-abs-error-truths.csv')) # score needed for MAE calculation Score.ensure_all_scores_exist() cls.score = Score.objects.filter( abbreviation='abs_error').first() # hard-coded official abbrev cls.score.update_score_for_model(cls.forecast_model)
def test_model_score_change_forecasts(self): # creating a new model should set its score_change.changed_at project2 = Project.objects.create() make_cdc_units_and_targets(project2) time_zero = TimeZero.objects.create( project=project2, timezero_date=datetime.date.today()) forecast_model2 = ForecastModel.objects.create(project=project2, name='name', abbreviation='abbrev') self.assertIsInstance(forecast_model2.score_change.changed_at, datetime.datetime) # adding a forecast should update its model's score_change.changed_at before_changed_at = forecast_model2.score_change.changed_at csv_file_path = Path( 'forecast_app/tests/EW1-KoTsarima-2017-01-17-small.csv' ) # EW01 2017 forecast2 = load_cdc_csv_forecast_file(2016, forecast_model2, csv_file_path, time_zero) self.assertNotEqual(before_changed_at, forecast_model2.score_change.changed_at) self.assertLess( before_changed_at, forecast_model2.score_change.changed_at) # was updated later # deleting a forecast should update its model's score_change.changed_at before_changed_at = forecast_model2.score_change.changed_at forecast2.delete() self.assertNotEqual(before_changed_at, forecast_model2.score_change.changed_at) self.assertLess( before_changed_at, forecast_model2.score_change.changed_at) # was updated later # bulk-deleting a model's forecasts will update its score_change.changed_at. (this basically tests that a signal # is used instead of a customized delete() - see set_model_changed_at() comment for idx in range(2): csv_file_path = Path( 'forecast_app/tests/EW1-KoTsarima-2017-01-17-small.csv' ) # EW01 2017 forecast = load_cdc_csv_forecast_file(2016, forecast_model2, csv_file_path, time_zero) forecast.issue_date += datetime.timedelta( days=idx + 1) # newer version avoids unique constraint errors forecast.save() before_changed_at = forecast_model2.score_change.changed_at forecast_model2.forecasts.all().delete() self.assertNotEqual(before_changed_at, forecast_model2.score_change.changed_at) self.assertLess( before_changed_at, forecast_model2.score_change.changed_at) # was updated later
def load_cdc_csv_forecasts_from_dir(forecast_model, data_dir, season_start_year): """ Adds Forecast objects to forecast_model using the cdc csv files under data_dir. Assumes TimeZeros match those in my Project. Skips files that have already been loaded. Skips files that cause load_forecast() to raise a RuntimeError. :param forecast_model: a ForecastModel to load the data into :param data_dir: Path of the directory that contains cdc csv files :param season_start_year: optional (used only if the files in data_dir have the date-related targets 'Season onset' or 'Season peak week') :return list of loaded Forecasts """ forecasts = [] for cdc_csv_file, timezero_date, _, _ in cdc_csv_components_from_data_dir(data_dir): timezero = forecast_model.project.time_zero_for_timezero_date(timezero_date) if not timezero: click.echo("x (no TimeZero found)\t{}\t".format(cdc_csv_file.name)) continue found_forecast_for_time_zero = forecast_model.forecast_for_time_zero(timezero) if found_forecast_for_time_zero: click.echo("s (found forecast)\t{}\t".format(cdc_csv_file.name)) continue try: forecast = load_cdc_csv_forecast_file(season_start_year, forecast_model, cdc_csv_file, timezero) forecasts.append(forecast) click.echo("o\t{}\t".format(cdc_csv_file.name)) except RuntimeError as rte: click.echo("f\t{}\t{}".format(cdc_csv_file.name, rte)) if not forecasts: click.echo("Warning: no valid forecast files found in directory: {}".format(data_dir)) return forecasts
def fill_cdc_project(project, mo_user, is_public): project.description = "description" project.home_url = "http://example.com/" project.core_data = "http://example.com/" # make the Units and Targets via cdc-project.json (recall it has no timezeros) make_cdc_units_and_targets(project) # make two TimeZeros - one for ground truth, and one for the forecast's data: # EW1-KoTsarima-2017-01-17-small.csv -> pymmwr.date_to_mmwr_week(datetime.date(2017, 1, 17)) # EW01 2017 # -> {'year': 2017, 'week': 3, 'day': 3} time_zero1 = TimeZero.objects.create(project=project, timezero_date=datetime.date( 2017, 1, 17), data_version_date=None) TimeZero.objects.create(project=project, timezero_date=datetime.date(2017, 1, 24), data_version_date=None) # load ground truth load_truth_data( project, Path('forecast_app/tests/truth_data/2017-01-17-truths.csv'), is_convert_na_none=True) # create the two models click.echo("creating ForecastModel") forecast_model1 = ForecastModel.objects.create( project=project, name=f'Test ForecastModel1 ({"public" if is_public else "private"})', abbreviation='model1_abbrev', team_name='ForecastModel1 team', description="a ForecastModel for testing", home_url='http://example.com', owner=mo_user) # load the forecasts using a small data file csv_file_path = Path( 'forecast_app/tests/EW1-KoTsarima-2017-01-17-small.csv') # EW01 2017 click.echo( "* loading forecast into forecast_model={}, csv_file_path={}".format( forecast_model1, csv_file_path)) start_time = timeit.default_timer() forecast1 = load_cdc_csv_forecast_file(2016, forecast_model1, csv_file_path, time_zero1) click.echo(" loaded forecast={}. {}".format( forecast1, timeit.default_timer() - start_time)) ForecastModel.objects.create( project=project, name=f'Test ForecastModel2 ({"public" if is_public else "private"})', abbreviation='model2_abbrev', # team_name='ForecastModel2 team', # leave default ('') description="a second ForecastModel for testing", home_url='http://example.com', owner=mo_user)
def test_num_pred_ele_rows_all_models(self): # 154 initial (11 * 7 * 2 = locations * targets * points/bins) self.assertEqual( 11 * 7 * 2, self.project.num_pred_ele_rows_all_models(is_oracle=False)) time_zero2 = TimeZero.objects.create(project=self.project, timezero_date=datetime.date( 2017, 1, 2)) # EW01 2017. 165 rows, 6 zero bins. same number of unique prediction elements, though csv_file_path = Path( 'forecast_app/tests/EW1-KoTsarima-2017-01-17-small.csv') load_cdc_csv_forecast_file(2016, self.forecast_model, csv_file_path, time_zero2) self.assertEqual( (11 * 7 * 2) * 2, self.project.num_pred_ele_rows_all_models(is_oracle=False))
def setUpTestData(cls): cls.project = Project.objects.create() make_cdc_units_and_targets(cls.project) cls.forecast_model = ForecastModel.objects.create( project=cls.project, name='name', abbreviation='abbrev') csv_file_path = Path( 'forecast_app/tests/model_error/ensemble/EW1-KoTstable-2017-01-17.csv' ) # EW01 2017 time_zero = TimeZero.objects.create( project=cls.project, timezero_date=(pymmwr.mmwr_week_to_date(2017, 1))) cls.forecast1 = load_cdc_csv_forecast_file(2016, cls.forecast_model, csv_file_path, time_zero) csv_file_path = Path( 'forecast_app/tests/model_error/ensemble/EW2-KoTstable-2017-01-23.csv' ) # EW02 2017 time_zero = TimeZero.objects.create( project=cls.project, timezero_date=(pymmwr.mmwr_week_to_date(2017, 2))) cls.forecast2 = load_cdc_csv_forecast_file(2016, cls.forecast_model, csv_file_path, time_zero) csv_file_path = Path( 'forecast_app/tests/model_error/ensemble/EW51-KoTstable-2017-01-03.csv' ) # EW51 2016 time_zero = TimeZero.objects.create( project=cls.project, timezero_date=(pymmwr.mmwr_week_to_date(2016, 51))) cls.forecast3 = load_cdc_csv_forecast_file(2016, cls.forecast_model, csv_file_path, time_zero) csv_file_path = Path( 'forecast_app/tests/model_error/ensemble/EW52-KoTstable-2017-01-09.csv' ) # EW52 2016 time_zero = TimeZero.objects.create( project=cls.project, timezero_date=(pymmwr.mmwr_week_to_date(2016, 52))) cls.forecast4 = load_cdc_csv_forecast_file(2016, cls.forecast_model, csv_file_path, time_zero)
def test_cdc_forecast_data_validation(self): with self.assertRaises(RuntimeError) as context: csv_file_path = Path( 'forecast_app/tests/EW1-bad-point-na-2017-01-17.csv' ) # EW01 2017 load_cdc_csv_forecast_file(2016, self.forecast_model, csv_file_path, self.time_zero) self.assertIn( "None point values are only valid for 'Season onset' targets", str(context.exception)) with self.assertRaises(RuntimeError) as context: csv_file_path = Path( 'forecast_app/tests/EW1-bin-doesnt-sum-to-one-2017-01-17.csv' ) # EW01 2017 load_cdc_csv_forecast_file(2016, self.forecast_model, csv_file_path, self.time_zero) self.assertIn( "Entries in the database rows in the `prob` column must be numbers in [0, 1]", str(context.exception)) try: # date-based Point row w/NA value is OK: csv_file_path = Path( 'forecast_app/tests/EW1-ok-point-na-2017-01-17.csv' ) # EW01 2017 load_cdc_csv_forecast_file(2016, self.forecast_model, csv_file_path, self.time_zero) except Exception as ex: self.fail(f"unexpected exception: {ex}")
def test_d3_foresight_out_of_season(self): project = Project.objects.create() make_cdc_units_and_targets(project) # pymmwr.mmwr_week_to_date(2016, 29) -> datetime.date(2016, 7, 17): time_zero = TimeZero.objects.create( project=project, timezero_date=datetime.date(2016, 7, 17), # 29 < SEASON_START_EW_NUMBER data_version_date=None, is_season_start=True, season_name='2016') # 20161030-KoTstable-20161114.cdc.csv {'year': 2016, 'week': 44, 'day': 1} -> datetime.date(2016, 10, 30): TimeZero.objects.create( project=project, timezero_date=datetime.date(2016, 10, 30), data_version_date=None, is_season_start=True, season_name='2017') # season has no forecast data forecast_model = ForecastModel.objects.create( project=project, name='forecast_model1 name', abbreviation='abbrev') csv_file_path = Path( 'forecast_app/tests/EW1-KoTsarima-2017-01-17-small.csv' ) # EW01 2017 load_cdc_csv_forecast_file(2016, forecast_model, csv_file_path, time_zero) with open( 'forecast_app/tests/EW1-KoTsarima-2017-01-17-small-exp-flusight-no-points.json', 'r') as fp: exp_json_template_str = fp.read() exp_json_template = Template(exp_json_template_str) exp_json_str = exp_json_template.render( Context({'forecast_model_id': forecast_model.id})) exp_flusight_data_dict = json.loads(exp_json_str) act_flusight_data_dict = flusight_unit_to_data_dict( project, '2017') self.assertEqual(exp_flusight_data_dict, act_flusight_data_dict)
def setUpTestData(cls): cls.project = Project.objects.create() cls.time_zero = TimeZero.objects.create(project=cls.project, timezero_date=datetime.date( 2017, 1, 1)) make_cdc_units_and_targets(cls.project) cls.forecast_model = ForecastModel.objects.create( project=cls.project, name='fm1', abbreviation='abbrev') csv_file_path = Path( 'forecast_app/tests/model_error/ensemble/EW1-KoTstable-2017-01-17.csv' ) # EW01 2017 cls.forecast = load_cdc_csv_forecast_file(2016, cls.forecast_model, csv_file_path, cls.time_zero)
def test_load_forecast_created_at_field(self): project2 = Project.objects.create() make_cdc_units_and_targets(project2) time_zero2 = TimeZero.objects.create( project=project2, timezero_date=datetime.date.today()) forecast_model2 = ForecastModel.objects.create(project=project2, name='name', abbreviation='abbrev') csv_file_path = Path( 'forecast_app/tests/EW1-KoTsarima-2017-01-17-small.csv' ) # EW01 2017 forecast2 = load_cdc_csv_forecast_file(2016, forecast_model2, csv_file_path, time_zero2) self.assertIsNotNone(forecast2.created_at)
def test_d3_foresight(self): project = Project.objects.create() make_cdc_units_and_targets(project) time_zero = TimeZero.objects.create( project=project, timezero_date=datetime.date(2016, 10, 23), # 20161023-KoTstable-20161109.cdc.csv {'year': 2016, 'week': 43, 'day': 1} data_version_date=datetime.date(2016, 10, 22)) # -> outputs dataVersionTime TimeZero.objects.create( project=project, timezero_date=datetime.date(2016, 10, 30), # 20161030-KoTstable-20161114.cdc.csv {'year': 2016, 'week': 44, 'day': 1} data_version_date=datetime.date(2016, 10, 29)) forecast_model1 = ForecastModel.objects.create( project=project, name='forecast_model1 name', abbreviation='abbrev') csv_file_path = Path( 'forecast_app/tests/EW1-KoTsarima-2017-01-17-small.csv' ) # EW01 2017 load_cdc_csv_forecast_file(2016, forecast_model1, csv_file_path, time_zero) # we treat the json file as a Django's template b/c mode lIDs are hard-coded, but can vary depending on the # RDBMS with open( 'forecast_app/tests/EW1-KoTsarima-2017-01-17-small-exp-flusight.json', 'r') as fp: exp_json_template_str = fp.read() exp_json_template = Template(exp_json_template_str) exp_json_str = exp_json_template.render( Context({'forecast_model_id': forecast_model1.id})) exp_flusight_data_dict = json.loads(exp_json_str) act_flusight_data_dict = flusight_unit_to_data_dict(project, None) self.assertEqual(exp_flusight_data_dict, act_flusight_data_dict)
def test_forecast_for_time_zero(self): time_zero = TimeZero.objects.create( project=self.project, timezero_date=datetime.date.today(), data_version_date=None) self.assertEqual(None, self.forecast_model.forecast_for_time_zero(time_zero)) csv_file_path = Path( 'forecast_app/tests/EW1-KoTsarima-2017-01-17.csv') # EW01 2017 forecast2 = load_cdc_csv_forecast_file(2016, self.forecast_model, csv_file_path, time_zero) self.assertEqual(forecast2, self.forecast_model.forecast_for_time_zero(time_zero)) forecast2.delete()
def setUpTestData(cls): cls.project = Project.objects.create() make_cdc_units_and_targets(cls.project) cls.forecast_model = ForecastModel.objects.create( project=cls.project, name='name', abbreviation='abbrev') cls.time_zero = TimeZero.objects.create(project=cls.project, timezero_date=datetime.date( 2017, 1, 1)) csv_file_path = Path( 'forecast_app/tests/model_error/ensemble/EW1-KoTstable-2017-01-17.csv' ) # EW01 2017 cls.forecast = load_cdc_csv_forecast_file(2016, cls.forecast_model, csv_file_path, cls.time_zero) cls.forecast.issued_at -= datetime.timedelta( days=1) # older version avoids unique constraint errors cls.forecast.save()
def test_delete_forecast(self): # add a second forecast version, check its rows were added, delete it, and test that the data was deleted (via # CASCADE) self.assertEqual( 1, self.forecast_model.forecasts.count()) # from setUpTestData() self.assertEqual(11 * 7 * 2, self.forecast.pred_eles.count() ) # locations * targets * points/bins csv_file_path = Path( 'forecast_app/tests/EW1-KoTsarima-2017-01-17.csv') # EW01 2017 forecast2 = load_cdc_csv_forecast_file(2016, self.forecast_model, csv_file_path, self.time_zero) self.assertEqual(2, self.forecast_model.forecasts.count()) # now two self.assertEqual(11 * 7 * 2, self.forecast.pred_eles.count()) # turns out there are the 17 duplicates that are not loaded. MUS: from an sqlite3 run: # f cls u t is_r hash # [(2, 2, 1, 1, 0, 'af49e5f6850e59638eb322a2293bd6c4'), # {'value': '2016-12-26'} 'HHS Region 1', 'Season onset' # (2, 2, 1, 2, 0, 'edb5fbaf20fbba5d1d1455d864f2bc95'), # {'value': '2017-02-06'} 'HHS Region 1', 'Season peak week' # (2, 2, 10, 1, 0, '73c3608a9829c5fe4103d1fd2b26c369'), # {'value': '2016-12-12'} 'HHS Region 10', 'Season onset' # (2, 2, 10, 2, 0, '5959bec40e3eb79763a6cd78e150e145'), # {'value': '2017-01-09'} 'HHS Region 10', 'Season peak week' # (2, 2, 2, 1, 0, 'f0cc965a8f901a09412f4a8e87c5aa3e'), # {'value': '2016-11-21'} # (2, 2, 3, 1, 0, '0f6791070c029b74186f03f98e487b59'), # {'value': '2016-12-19'} # (2, 2, 4, 1, 0, '3b2bdabc810ce299f0e35a55b107c374'), # {'value': '2016-11-14'} # (2, 2, 4, 2, 0, '177183a5a9c19cedca454389aa796aee'), # {'value': '2017-02-13'} # (2, 2, 5, 1, 0, 'af49e5f6850e59638eb322a2293bd6c4'), # {'value': '2016-12-26'} # (2, 2, 6, 1, 0, 'af49e5f6850e59638eb322a2293bd6c4'), # {'value': '2016-12-26'} ... # (2, 2, 6, 2, 0, '177183a5a9c19cedca454389aa796aee'), # {'value': '2017-02-13'} # (2, 2, 7, 1, 0, 'af49e5f6850e59638eb322a2293bd6c4'), # {'value': '2016-12-26'} # (2, 2, 8, 1, 0, '0f6791070c029b74186f03f98e487b59'), # {'value': '2016-12-19'} # (2, 2, 9, 1, 0, '0f6791070c029b74186f03f98e487b59'), # {'value': '2016-12-19'} # (2, 2, 9, 2, 0, 'edb5fbaf20fbba5d1d1455d864f2bc95'), # {'value': '2017-02-06'} # (2, 2, 11, 1, 0, '73c3608a9829c5fe4103d1fd2b26c369'), # {'value': '2016-12-12'} 'US National', 'Season onset' # (2, 2, 11, 2, 0, '86bf4bd34d86b349754bcc7412857faa') # {'value': '2017-01-30'} 'US National', 'Season peak week' # ] self.assertEqual( (11 * 7 * 2 - 17), forecast2.pred_eles.count()) # 154 - 17 duplicates = 137 forecast2.delete() self.assertEqual(1, self.forecast_model.forecasts.count()) # back to one self.assertEqual(0, forecast2.pred_eles.count())
def test_delete_forecast(self): # add a second forecast, check its rows were added, delete it, and test that the data was deleted (via CASCADE) self.assertEqual( 1, self.forecast_model.forecasts.count()) # from setUpTestData() self.assertEqual(8019, self.forecast.get_num_rows()) # "" csv_file_path = Path( 'forecast_app/tests/EW1-KoTsarima-2017-01-17.csv') # EW01 2017 forecast2 = load_cdc_csv_forecast_file(2016, self.forecast_model, csv_file_path, self.time_zero) self.assertEqual(2, self.forecast_model.forecasts.count()) # includes new self.assertEqual(5237, forecast2.get_num_rows( )) # 8019 total rows - 2782 zero-valued bin rows = 5237 non-zero self.assertEqual(8019, self.forecast.get_num_rows()) # didn't change forecast2.delete() self.assertEqual(1, self.forecast_model.forecasts.count()) # back to one self.assertEqual(0, forecast2.get_num_rows()) # cascaded DELETE
def test_load_forecast(self): self.assertEqual(1, len(self.forecast_model.forecasts.all())) self.assertIsInstance(self.forecast, Forecast) self.assertEqual('EW1-KoTstable-2017-01-17.csv', self.forecast.source) self.assertEqual(11 * 7 * 2, self.forecast.pred_eles.count() ) # locations * targets * points/bins # check 'US National' targets: spot-check a few point rows act_points_qs = self.forecast.pred_eles.filter( unit__name='US National', pred_class=PredictionElement.POINT_CLASS) self.assertEqual(7, act_points_qs.count()) # test empty file with self.assertRaises(RuntimeError) as context: csv_file_path = Path( 'forecast_app/tests/EW1-bad_file_no_header-2017-01-17.csv' ) # EW01 2017? load_cdc_csv_forecast_file(2016, self.forecast_model, csv_file_path, self.time_zero) self.assertIn('empty file', str(context.exception)) # test a bad data file header with self.assertRaises(RuntimeError) as context: csv_file_path = Path( 'forecast_app/tests/EW1-bad_file_header-2017-01-17.csv' ) # EW01 2017? load_cdc_csv_forecast_file(2016, self.forecast_model, csv_file_path, self.time_zero) self.assertIn('invalid header', str(context.exception)) # test load_forecast() with timezero not in the project project2 = Project.objects.create() # no TimeZeros make_cdc_units_and_targets(project2) forecast_model2 = ForecastModel.objects.create(project=project2, name='name', abbreviation='abbrev') with self.assertRaises(RuntimeError) as context: csv_file_path = Path( 'forecast_app/tests/model_error/ensemble/EW1-KoTstable-2017-01-17.csv' ) # EW01 2017 load_cdc_csv_forecast_file(2016, forecast_model2, csv_file_path, self.time_zero) self.assertIn("time_zero was not in project", str(context.exception))
def test__tz_unit_targ_pks_to_truth_values(self): # setup project = Project.objects.create() make_cdc_units_and_targets(project) # load truth only for the TimeZero in truths-2016-2017-reichlab.csv we're testing against time_zero = TimeZero.objects.create(project=project, timezero_date=datetime.date( 2017, 1, 1), is_season_start=True, season_name='season1') load_truth_data( project, Path( 'utils/ensemble-truth-table-script/truths-2016-2017-reichlab.csv' )) forecast_model = ForecastModel.objects.create(project=project, name='test model', abbreviation='abbrev') csv_file_path = Path( 'forecast_app/tests/EW1-KoTsarima-2017-01-17-small.csv' ) # EW01 2017 load_cdc_csv_forecast_file(2016, forecast_model, csv_file_path, time_zero) # test tz_pk = time_zero.pk loc1_pk = Unit.objects.filter(project=project, name='HHS Region 1').first().pk loc2_pk = Unit.objects.filter(project=project, name='HHS Region 2').first().pk loc3_pk = Unit.objects.filter(project=project, name='HHS Region 3').first().pk loc4_pk = Unit.objects.filter(project=project, name='HHS Region 4').first().pk loc5_pk = Unit.objects.filter(project=project, name='HHS Region 5').first().pk loc6_pk = Unit.objects.filter(project=project, name='HHS Region 6').first().pk loc7_pk = Unit.objects.filter(project=project, name='HHS Region 7').first().pk loc8_pk = Unit.objects.filter(project=project, name='HHS Region 8').first().pk loc9_pk = Unit.objects.filter(project=project, name='HHS Region 9').first().pk loc10_pk = Unit.objects.filter(project=project, name='HHS Region 10').first().pk loc11_pk = Unit.objects.filter(project=project, name='US National').first().pk target1_pk = Target.objects.filter(project=project, name='Season onset').first().pk target2_pk = Target.objects.filter(project=project, name='Season peak week').first().pk target3_pk = Target.objects.filter( project=project, name='Season peak percentage').first().pk target4_pk = Target.objects.filter(project=project, name='1 wk ahead').first().pk target5_pk = Target.objects.filter(project=project, name='2 wk ahead').first().pk target6_pk = Target.objects.filter(project=project, name='3 wk ahead').first().pk target7_pk = Target.objects.filter(project=project, name='4 wk ahead').first().pk exp_dict = { # {timezero_pk: {unit_pk: {target_id: truth_value}}} tz_pk: { loc1_pk: { target1_pk: ['2016-12-25'], target2_pk: [datetime.date(2017, 2, 5)], target3_pk: [3.19221], target4_pk: [1.52411], target5_pk: [1.73987], target6_pk: [2.06524], target7_pk: [2.51375] }, loc2_pk: { target1_pk: ['2016-11-20'], target2_pk: [datetime.date(2017, 2, 5)], target3_pk: [6.93759], target4_pk: [5.07086], target5_pk: [5.68166], target6_pk: [6.01053], target7_pk: [6.49829] }, loc3_pk: { target1_pk: ['2016-12-18'], target2_pk: [datetime.date(2017, 2, 12)], target3_pk: [5.20003], target4_pk: [2.81366], target5_pk: [3.09968], target6_pk: [3.45232], target7_pk: [3.73339] }, loc4_pk: { target1_pk: ['2016-11-13'], target2_pk: [datetime.date(2017, 2, 12)], target3_pk: [5.5107], target4_pk: [2.89395], target5_pk: [3.68564], target6_pk: [3.69188], target7_pk: [4.53169] }, loc5_pk: { target1_pk: ['2016-12-25'], target2_pk: [datetime.date(2017, 2, 12)], target3_pk: [4.31787], target4_pk: [2.11757], target5_pk: [2.4432], target6_pk: [2.76295], target7_pk: [3.182] }, loc6_pk: { target1_pk: ['2017-01-08'], target2_pk: [datetime.date(2017, 2, 5)], target3_pk: [9.87589], target4_pk: [4.80185], target5_pk: [5.26955], target6_pk: [6.10427], target7_pk: [8.13221] }, loc7_pk: { target1_pk: ['2016-12-25'], target2_pk: [datetime.date(2017, 2, 5)], target3_pk: [6.35948], target4_pk: [2.75581], target5_pk: [3.46528], target6_pk: [4.56991], target7_pk: [5.52653] }, loc8_pk: { target1_pk: ['2016-12-18'], target2_pk: [datetime.date(2017, 2, 12)], target3_pk: [2.72703], target4_pk: [1.90851], target5_pk: [2.2668], target6_pk: [2.07104], target7_pk: [2.27632] }, loc9_pk: { target1_pk: ['2016-12-18'], target2_pk: [datetime.date(2016, 12, 25)], target3_pk: [3.30484], target4_pk: [2.83778], target5_pk: [2.68071], target6_pk: [2.9577], target7_pk: [3.03987] }, loc10_pk: { target1_pk: ['2016-12-11'], target2_pk: [datetime.date(2016, 12, 25)], target3_pk: [3.67061], target4_pk: [2.15197], target5_pk: [3.25108], target6_pk: [2.51434], target7_pk: [2.28634] }, loc11_pk: { target1_pk: ['2016-12-11'], target2_pk: [datetime.date(2017, 2, 5)], target3_pk: [5.06094], target4_pk: [3.07623], target5_pk: [3.50708], target6_pk: [3.79872], target7_pk: [4.43601] } } } act_dict = _tz_unit_targ_pks_to_truth_values(forecast_model.project) self.assertEqual(exp_dict, act_dict)
def test_load_forecast(self): self.assertEqual(1, len(self.forecast_model.forecasts.all())) self.assertIsInstance(self.forecast, Forecast) self.assertEqual('EW1-KoTstable-2017-01-17.csv', self.forecast.source) self.assertEqual(8019, self.forecast.get_num_rows()) # excluding header # check 'US National' targets: spot-check a few point rows exp_points = [ ('US National', '1 wk ahead', None, 3.00101461253164, None, None, None), # _i, _f, _t, _d, _b ('US National', '2 wk ahead', None, 2.72809349594878, None, None, None), ('US National', '3 wk ahead', None, 2.5332588357381, None, None, None), ('US National', '4 wk ahead', None, 2.42985946508278, None, None, None), ('US National', 'Season onset', None, None, '2016-12-12', None, None), ('US National', 'Season peak percentage', None, 3.30854920241938, None, None, None), ('US National', 'Season peak week', None, None, None, datetime.date(2017, 1, 30), None) ] act_points_qs = self.forecast.point_prediction_qs() \ .filter(unit__name='US National') \ .order_by('unit__name', 'target__name') \ .values_list('unit__name', 'target__name', 'value_i', 'value_f', 'value_t', 'value_d', 'value_b') self.assertEqual(exp_points, list(act_points_qs)) # test empty file with self.assertRaises(RuntimeError) as context: csv_file_path = Path( 'forecast_app/tests/EW1-bad_file_no_header-2017-01-17.csv' ) # EW01 2017? load_cdc_csv_forecast_file(2016, self.forecast_model, csv_file_path, self.time_zero) self.assertIn('empty file', str(context.exception)) # test a bad data file header with self.assertRaises(RuntimeError) as context: csv_file_path = Path( 'forecast_app/tests/EW1-bad_file_header-2017-01-17.csv' ) # EW01 2017? load_cdc_csv_forecast_file(2016, self.forecast_model, csv_file_path, self.time_zero) self.assertIn('invalid header', str(context.exception)) # test load_forecast() with timezero not in the project project2 = Project.objects.create() # no TimeZeros make_cdc_units_and_targets(project2) forecast_model2 = ForecastModel.objects.create(project=project2, name='name', abbreviation='abbrev') with self.assertRaises(RuntimeError) as context: csv_file_path = Path( 'forecast_app/tests/model_error/ensemble/EW1-KoTstable-2017-01-17.csv' ) # EW01 2017 load_cdc_csv_forecast_file(2016, forecast_model2, csv_file_path, self.time_zero) self.assertIn("time_zero was not in project", str(context.exception))