From 20a46d2e6f641763e96b80995218cf62324f05b1 Mon Sep 17 00:00:00 2001 From: Jingjing Tang Date: Tue, 11 Jan 2022 00:16:20 -0500 Subject: [PATCH 01/31] add age groups --- .../delphi_quidel_covidtest/constants.py | 10 ++ .../delphi_quidel_covidtest/data_tools.py | 3 +- .../generate_sensor.py | 53 ++++---- .../delphi_quidel_covidtest/geo_maps.py | 12 +- .../delphi_quidel_covidtest/pull.py | 56 ++++++++- .../delphi_quidel_covidtest/run.py | 113 ++++++++++-------- 6 files changed, 165 insertions(+), 82 deletions(-) diff --git a/quidel_covidtest/delphi_quidel_covidtest/constants.py b/quidel_covidtest/delphi_quidel_covidtest/constants.py index abe88c7b1..f99dca028 100644 --- a/quidel_covidtest/delphi_quidel_covidtest/constants.py +++ b/quidel_covidtest/delphi_quidel_covidtest/constants.py @@ -39,3 +39,13 @@ # SMOOTHED_TEST_PER_DEVICE: (True, True), # RAW_TEST_PER_DEVICE: (True, False) } +AGE_GROUPS = [ + "total", + "age_0to5", + "age_5to13", + "age_14to17", + "age_18to49", + "age_50to64", + "age_65to74", + "age_75toOlder" +] diff --git a/quidel_covidtest/delphi_quidel_covidtest/data_tools.py b/quidel_covidtest/delphi_quidel_covidtest/data_tools.py index f89a353ed..fd346a080 100644 --- a/quidel_covidtest/delphi_quidel_covidtest/data_tools.py +++ b/quidel_covidtest/delphi_quidel_covidtest/data_tools.py @@ -112,7 +112,8 @@ def _geographical_pooling(tpooled_tests, tpooled_ptests, min_obs): # Can't borrow more than total no. observations. # Relies on the fact that np.inf > 1 borrow_prop[borrow_prop > 1] = 1 - return borrow_prop + #TODO + return [0 for i in range(len(borrow_prop))] def raw_positive_prop(positives, tests, min_obs): diff --git a/quidel_covidtest/delphi_quidel_covidtest/generate_sensor.py b/quidel_covidtest/delphi_quidel_covidtest/generate_sensor.py index ba6b443c6..ae3304e02 100644 --- a/quidel_covidtest/delphi_quidel_covidtest/generate_sensor.py +++ b/quidel_covidtest/delphi_quidel_covidtest/generate_sensor.py @@ -10,7 +10,8 @@ MIN_OBS = 50 # minimum number of observations in order to compute a proportion. POOL_DAYS = 7 -def generate_sensor_for_nonparent_geo(state_groups, res_key, smooth, device, first_date, last_date): +def generate_sensor_for_nonparent_geo(state_groups, res_key, smooth, device, + first_date, last_date, suffix): """ Fit over geo resolutions that don't use a parent state (nation/hhs/state). @@ -21,6 +22,8 @@ def generate_sensor_for_nonparent_geo(state_groups, res_key, smooth, device, fir Consider raw or smooth device: bool Consider test_per_device or pct_positive + suffix: str + Indicate the age group Returns: df: pd.DataFrame """ @@ -35,27 +38,27 @@ def generate_sensor_for_nonparent_geo(state_groups, res_key, smooth, device, fir # smoothed test per device if device & smooth: stat, se, sample_size = smoothed_tests_per_device( - devices=state_group["numUniqueDevices"].values, + devices=state_group["numUniqueDevices_%s"%suffix].values, tests=state_group['totalTest'].values, min_obs=MIN_OBS, pool_days=POOL_DAYS) # raw test per device elif device & (not smooth): stat, se, sample_size = raw_tests_per_device( - devices=state_group["numUniqueDevices"].values, + devices=state_group["numUniqueDevices_s"%suffix].values, tests=state_group['totalTest'].values, min_obs=MIN_OBS) # smoothed pct positive elif (not device) & smooth: stat, se, sample_size = smoothed_positive_prop( - tests=state_group['totalTest'].values, - positives=state_group['positiveTest'].values, + tests=state_group['totalTest_%s'%suffix].values, + positives=state_group['positiveTest_%s'%suffix].values, min_obs=MIN_OBS, pool_days=POOL_DAYS) stat = stat * 100 # raw pct positive else: stat, se, sample_size = raw_positive_prop( - tests=state_group['totalTest'].values, - positives=state_group['positiveTest'].values, + tests=state_group['totalTest_%s'%suffix].values, + positives=state_group['positiveTest_%s'%suffix].values, min_obs=MIN_OBS) stat = stat * 100 @@ -68,7 +71,7 @@ def generate_sensor_for_nonparent_geo(state_groups, res_key, smooth, device, fir return remove_null_samples(state_df) def generate_sensor_for_parent_geo(state_groups, data, res_key, smooth, - device, first_date, last_date): + device, first_date, last_date, suffix): """ Fit over geo resolutions that use a parent state (county/hrr/msa). @@ -79,6 +82,8 @@ def generate_sensor_for_parent_geo(state_groups, data, res_key, smooth, Consider raw or smooth device: bool Consider test_per_device or pct_positive + suffix: str + Indicate the age group Returns: df: pd.DataFrame """ @@ -104,41 +109,41 @@ def generate_sensor_for_parent_geo(state_groups, data, res_key, smooth, if has_parent: if device: stat, se, sample_size = smoothed_tests_per_device( - devices=res_group["numUniqueDevices"].values, - tests=res_group['totalTest'].values, + devices=res_group["numUniqueDevices_%s"%suffix].values, + tests=res_group['totalTest_%s'%suffix].values, min_obs=MIN_OBS, pool_days=POOL_DAYS, - parent_devices=res_group["numUniqueDevices_parent"].values, - parent_tests=res_group["totalTest_parent"].values) + parent_devices=res_group["numUniqueDevices_%s_parent"%suffix].values, + parent_tests=res_group["totalTest_%s_parent"%suffix].values) else: stat, se, sample_size = smoothed_positive_prop( - tests=res_group['totalTest'].values, - positives=res_group['positiveTest'].values, + tests=res_group['totalTest_%s'%suffix].values, + positives=res_group['positiveTest_%s'%suffix].values, min_obs=MIN_OBS, pool_days=POOL_DAYS, - parent_tests=res_group["totalTest_parent"].values, - parent_positives=res_group['positiveTest_parent'].values) + parent_tests=res_group["totalTest_%s_parent"%suffix].values, + parent_positives=res_group['positiveTest_%s_parent'%suffix].values) stat = stat * 100 else: if device: stat, se, sample_size = smoothed_tests_per_device( - devices=res_group["numUniqueDevices"].values, - tests=res_group['totalTest'].values, + devices=res_group["numUniqueDevices_%s"%suffix].values, + tests=res_group['totalTest_%s'%suffix].values, min_obs=MIN_OBS, pool_days=POOL_DAYS) else: stat, se, sample_size = smoothed_positive_prop( - tests=res_group['totalTest'].values, - positives=res_group['positiveTest'].values, + tests=res_group['totalTest_%s'%suffix].values, + positives=res_group['positiveTest_%s'%suffix].values, min_obs=MIN_OBS, pool_days=POOL_DAYS) stat = stat * 100 else: if device: stat, se, sample_size = raw_tests_per_device( - devices=res_group["numUniqueDevices"].values, - tests=res_group['totalTest'].values, + devices=res_group["numUniqueDevices_%s"%suffix].values, + tests=res_group['totalTest_%s'%suffix].values, min_obs=MIN_OBS) else: stat, se, sample_size = raw_positive_prop( - tests=res_group['totalTest'].values, - positives=res_group['positiveTest'].values, + tests=res_group['totalTest_%s'%suffix].values, + positives=res_group['positiveTest_%s'%suffix].values, min_obs=MIN_OBS) stat = stat * 100 diff --git a/quidel_covidtest/delphi_quidel_covidtest/geo_maps.py b/quidel_covidtest/delphi_quidel_covidtest/geo_maps.py index 7ebdcc834..33b7c4830 100644 --- a/quidel_covidtest/delphi_quidel_covidtest/geo_maps.py +++ b/quidel_covidtest/delphi_quidel_covidtest/geo_maps.py @@ -13,14 +13,22 @@ } -def geo_map(geo_res, df): +def geo_map(geo_res, df, agegroup): """Map a geocode to a new value.""" data = df.copy() geo_key = GEO_KEY_DICT[geo_res] # Add population for each zipcode data = GMPR.add_population_column(data, "zip") # zip -> geo_res - data = GMPR.replace_geocode(data, "zip", geo_key, data_cols=DATA_COLS) + data_cols = [] + for data_col in DATA_COLS: + if data_col != "population": + data_cols.append("_".join([data_col, agegroup])) + else: + data_cols.append(data_col) + data = GMPR.replace_geocode( + data, from_code="zip", new_code=geo_key, date_col = "timestamp", + data_cols=data_cols) if geo_res in ["state", "hhs", "nation"]: return data, geo_key # Add parent state diff --git a/quidel_covidtest/delphi_quidel_covidtest/pull.py b/quidel_covidtest/delphi_quidel_covidtest/pull.py index 3efa9ed23..eb14b2f21 100644 --- a/quidel_covidtest/delphi_quidel_covidtest/pull.py +++ b/quidel_covidtest/delphi_quidel_covidtest/pull.py @@ -163,21 +163,21 @@ def preprocess_new_data(start_date, end_date, params, test_mode, logger): overall_pos = df[df["OverallResult"] == "positive"].groupby( by=["timestamp", "zip"], as_index=False)['OverallResult'].count() - overall_pos["positiveTest"] = overall_pos["OverallResult"] + overall_pos["positiveTest_total"] = overall_pos["OverallResult"] overall_pos.drop(labels="OverallResult", axis="columns", inplace=True) # Compute overallTotal overall_total = df.groupby( by=["timestamp", "zip"], as_index=False)['OverallResult'].count() - overall_total["totalTest"] = overall_total["OverallResult"] + overall_total["totalTest_total"] = overall_total["OverallResult"] overall_total.drop(labels="OverallResult", axis="columns", inplace=True) # Compute numUniqueDevices numUniqueDevices = df.groupby( by=["timestamp", "zip"], as_index=False)["SofiaSerNum"].agg({"SofiaSerNum": "nunique"}).rename( - columns={"SofiaSerNum": "numUniqueDevices"} + columns={"SofiaSerNum": "numUniqueDevices_total"} ) df_merged = overall_total.merge( @@ -185,7 +185,55 @@ def preprocess_new_data(start_date, end_date, params, test_mode, logger): ).merge( overall_pos, on=["timestamp", "zip"], how="left" ).fillna(0).drop_duplicates() - + + # Compute Summary info for age groups + df["PatientAge"]= df["PatientAge"].fillna(-1) + df.loc[df["PatientAge"] == "<1", "PatientAge"] = 0.5 + df.loc[df["PatientAge"] == ">85", "PatientAge"] = 100 + df["PatientAge"] = df["PatientAge"] .astype(float) + + df["label"] = None + df.loc[df["PatientAge"] < 5, "label"] = "age_0to5" + df.loc[((df["PatientAge"] >= 5)) & (df["PatientAge"] < 14), "label"] = "age_5to13" + df.loc[((df["PatientAge"] >= 14)) & (df["PatientAge"] < 18), "label"] = "age_14to17" + df.loc[((df["PatientAge"] >= 18)) & (df["PatientAge"] < 50), "label"] = "age_18to49" + df.loc[((df["PatientAge"] >= 50)) & (df["PatientAge"] < 65), "label"] = "age_50to64" + df.loc[((df["PatientAge"] >= 65)) & (df["PatientAge"] < 75), "label"] = "age_65to74" + df.loc[df["PatientAge"] >= 75, "label"] = "age_75toOlder" + df.loc[df["PatientAge"] == -1, "label"] = "NA" + + for agegroup in df["label"].unique(): + if agegroup == "NA": + continue + # Compute overallPositive + group_pos = df.loc[(df["OverallResult"] == "positive") + & (df["label"] == agegroup)].groupby( + by=["timestamp", "zip"], + as_index=False)['OverallResult'].count() + group_pos["positiveTest_%s"%agegroup] = group_pos["OverallResult"] + group_pos.drop(labels="OverallResult", axis="columns", inplace=True) + + # Compute overallTotal + group_total = df.loc[df["label"] == agegroup].groupby( + by=["timestamp", "zip"], + as_index=False)['OverallResult'].count() + group_total["totalTest_%s"%agegroup] = group_total["OverallResult"] + group_total.drop(labels="OverallResult", axis="columns", inplace=True) + + # Compute numUniqueDevices + group_numUniqueDevices = df.loc[df["label"] == agegroup].groupby( + by=["timestamp", "zip"], + as_index=False)["SofiaSerNum"].agg({"SofiaSerNum": "nunique"}).rename( + columns={"SofiaSerNum": "numUniqueDevices_%s"%agegroup} + ) + + df_merged = df_merged.merge( + group_numUniqueDevices, on=["timestamp", "zip"], how="left" + ).merge( + group_pos, on=["timestamp", "zip"], how="left" + ).merge( + group_total, on=["timestamp", "zip"], how="left" + ).fillna(0).drop_duplicates() return df_merged, time_flag diff --git a/quidel_covidtest/delphi_quidel_covidtest/run.py b/quidel_covidtest/delphi_quidel_covidtest/run.py index 5f084440c..4ef95b795 100644 --- a/quidel_covidtest/delphi_quidel_covidtest/run.py +++ b/quidel_covidtest/delphi_quidel_covidtest/run.py @@ -18,7 +18,8 @@ from .constants import (END_FROM_TODAY_MINUS, SMOOTHED_POSITIVE, RAW_POSITIVE, SMOOTHED_TEST_PER_DEVICE, RAW_TEST_PER_DEVICE, - PARENT_GEO_RESOLUTIONS, SENSORS, SMOOTHERS, NONPARENT_GEO_RESOLUTIONS) + PARENT_GEO_RESOLUTIONS, SENSORS, SMOOTHERS, NONPARENT_GEO_RESOLUTIONS, + AGE_GROUPS) from .generate_sensor import generate_sensor_for_parent_geo, generate_sensor_for_nonparent_geo from .geo_maps import geo_map from .pull import (pull_quidel_covidtest, @@ -80,65 +81,75 @@ def run_module(params: Dict[str, Any]): if _end_date is None: logger.info("The data is up-to-date. Currently, no new data to be ingested.") return - export_end_date = check_export_end_date(export_end_date, _end_date, - END_FROM_TODAY_MINUS) - export_start_date = check_export_start_date(export_start_date, - export_end_date, export_day_range) + export_end_date = check_export_end_date( + export_end_date, _end_date, END_FROM_TODAY_MINUS) + export_start_date = check_export_start_date( + export_start_date, export_end_date, export_day_range) first_date, last_date = df["timestamp"].min(), df["timestamp"].max() - # State Level data = df.copy() # Add prefix, if required sensors = add_prefix(SENSORS, wip_signal=params["indicator"]["wip_signal"], prefix="wip_") smoothers = SMOOTHERS.copy() - for geo_res in NONPARENT_GEO_RESOLUTIONS: - geo_data, res_key = geo_map(geo_res, data) - geo_groups = geo_data.groupby(res_key) - for sensor in sensors: - logger.info("Generating signal and exporting to CSV", - geo_res=geo_res, - sensor=sensor) - if sensor.endswith(SMOOTHED_POSITIVE): - smoothers[sensor] = smoothers.pop(SMOOTHED_POSITIVE) - elif sensor.endswith(RAW_POSITIVE): - smoothers[sensor] = smoothers.pop(RAW_POSITIVE) - elif sensor.endswith(SMOOTHED_TEST_PER_DEVICE): - smoothers[sensor] = smoothers.pop(SMOOTHED_TEST_PER_DEVICE) - else: - smoothers[sensor] = smoothers.pop(RAW_TEST_PER_DEVICE) - state_df = generate_sensor_for_nonparent_geo( - geo_groups, res_key, smooth=smoothers[sensor][1], - device=smoothers[sensor][0], first_date=first_date, - last_date=last_date) - dates = create_export_csv( - state_df, - geo_res=geo_res, - sensor=sensor, - export_dir=export_dir, - start_date=export_start_date, - end_date=export_end_date) - if len(dates) > 0: - stats.append((max(dates), len(dates))) - - # County/HRR/MSA level - for geo_res in PARENT_GEO_RESOLUTIONS: - geo_data, res_key = geo_map(geo_res, data) - for sensor in sensors: - logger.info("Generating signal and exporting to CSV", - geo_res=geo_res, - sensor=sensor) - res_df = generate_sensor_for_parent_geo( - geo_groups, geo_data, res_key, smooth=smoothers[sensor][1], - device=smoothers[sensor][0], first_date=first_date, - last_date=last_date) - dates = create_export_csv(res_df, geo_res=geo_res, sensor=sensor, export_dir=export_dir, - start_date=export_start_date, end_date=export_end_date, - remove_null_samples=True) - if len(dates) > 0: - stats.append((max(dates), len(dates))) + for agegroup in AGE_GROUPS: + for geo_res in ["state"]:#NONPARENT_GEO_RESOLUTIONS: + geo_data, res_key = geo_map(geo_res, data, agegroup) + geo_groups = geo_data.groupby(res_key) + # for sensor in sensors: + # if agegroup == "total": + # sensor_name = sensor + # else: + # sensor_name = "_".join([sensor, agegroup]) + # logger.info("Generating signal and exporting to CSV", + # geo_res=geo_res, + # sensor=sensor) + # if sensor.endswith(SMOOTHED_POSITIVE): + # smoothers[sensor] = smoothers.pop(SMOOTHED_POSITIVE) + # elif sensor.endswith(RAW_POSITIVE): + # smoothers[sensor] = smoothers.pop(RAW_POSITIVE) + # elif sensor.endswith(SMOOTHED_TEST_PER_DEVICE): + # smoothers[sensor] = smoothers.pop(SMOOTHED_TEST_PER_DEVICE) + # else: + # smoothers[sensor] = smoothers.pop(RAW_TEST_PER_DEVICE) + # state_df = generate_sensor_for_nonparent_geo( + # geo_groups, res_key, smooth=smoothers[sensor][1], + # device=smoothers[sensor][0], first_date=first_date, + # last_date=last_date, suffix=agegroup) + # dates = create_export_csv( + # state_df, + # geo_res=geo_res, + # sensor=sensor_name, + # export_dir=export_dir, + # start_date=export_start_date, + # end_date=export_end_date) + # if len(dates) > 0: + # stats.append((max(dates), len(dates))) + + # County/HRR/MSA level + for geo_res in ["county"]:#PARENT_GEO_RESOLUTIONS: + geo_data, res_key = geo_map(geo_res, data, agegroup) + for sensor in sensors: + if agegroup == "total": + sensor_name = sensor + else: + sensor_name = "_".join([sensor, agegroup]) + logger.info("Generating signal and exporting to CSV", + geo_res=geo_res, + sensor=sensor) + res_df = generate_sensor_for_parent_geo( + geo_groups, geo_data, res_key, smooth=smoothers[sensor][1], + device=smoothers[sensor][0], first_date=first_date, + last_date=last_date, suffix=agegroup) + dates = create_export_csv(res_df, geo_res=geo_res, + sensor=sensor_name, export_dir=export_dir, + start_date=export_start_date, + end_date=export_end_date, + remove_null_samples=True) + if len(dates) > 0: + stats.append((max(dates), len(dates))) # Export the cache file if the pipeline runs successfully. # Otherwise, don't update the cache file From 801e2f5a131906d6e61858d4a4613b7a83d4eacb Mon Sep 17 00:00:00 2001 From: Jingjing Tang Date: Fri, 14 Jan 2022 01:41:27 -0500 Subject: [PATCH 02/31] update code for adding megacounties --- .../delphi_quidel_covidtest/constants.py | 15 ++-- .../delphi_quidel_covidtest/data_tools.py | 3 +- .../generate_sensor.py | 54 +++++++------ .../delphi_quidel_covidtest/geo_maps.py | 45 ++++++++--- .../delphi_quidel_covidtest/pull.py | 19 +++-- .../delphi_quidel_covidtest/run.py | 81 ++++++++++--------- 6 files changed, 122 insertions(+), 95 deletions(-) diff --git a/quidel_covidtest/delphi_quidel_covidtest/constants.py b/quidel_covidtest/delphi_quidel_covidtest/constants.py index f99dca028..af67aa788 100644 --- a/quidel_covidtest/delphi_quidel_covidtest/constants.py +++ b/quidel_covidtest/delphi_quidel_covidtest/constants.py @@ -3,7 +3,7 @@ MIN_OBS = 50 # minimum number of observations in order to compute a proportion. POOL_DAYS = 7 # number of days in the past (including today) to pool over END_FROM_TODAY_MINUS = 5 # report data until - X days -# Signal names +# Signal Types SMOOTHED_POSITIVE = "covid_ag_smoothed_pct_positive" RAW_POSITIVE = "covid_ag_raw_pct_positive" SMOOTHED_TEST_PER_DEVICE = "covid_ag_smoothed_test_per_device" @@ -22,6 +22,7 @@ HRR, ] +# state should be last one NONPARENT_GEO_RESOLUTIONS = [ HHS, NATION, @@ -41,11 +42,9 @@ } AGE_GROUPS = [ "total", - "age_0to5", - "age_5to13", - "age_14to17", - "age_18to49", - "age_50to64", - "age_65to74", - "age_75toOlder" + "age_0to4", + "age_5to17", + "age_18to49", + "age_50to64", + "age_65toOlder" ] diff --git a/quidel_covidtest/delphi_quidel_covidtest/data_tools.py b/quidel_covidtest/delphi_quidel_covidtest/data_tools.py index fd346a080..f89a353ed 100644 --- a/quidel_covidtest/delphi_quidel_covidtest/data_tools.py +++ b/quidel_covidtest/delphi_quidel_covidtest/data_tools.py @@ -112,8 +112,7 @@ def _geographical_pooling(tpooled_tests, tpooled_ptests, min_obs): # Can't borrow more than total no. observations. # Relies on the fact that np.inf > 1 borrow_prop[borrow_prop > 1] = 1 - #TODO - return [0 for i in range(len(borrow_prop))] + return borrow_prop def raw_positive_prop(positives, tests, min_obs): diff --git a/quidel_covidtest/delphi_quidel_covidtest/generate_sensor.py b/quidel_covidtest/delphi_quidel_covidtest/generate_sensor.py index ae3304e02..f43ed3071 100644 --- a/quidel_covidtest/delphi_quidel_covidtest/generate_sensor.py +++ b/quidel_covidtest/delphi_quidel_covidtest/generate_sensor.py @@ -6,9 +6,9 @@ smoothed_tests_per_device, raw_tests_per_device, remove_null_samples) +from .geo_maps import add_megacounties -MIN_OBS = 50 # minimum number of observations in order to compute a proportion. -POOL_DAYS = 7 +from .constants import (MIN_OBS, POOL_DAYS) def generate_sensor_for_nonparent_geo(state_groups, res_key, smooth, device, first_date, last_date, suffix): @@ -38,27 +38,27 @@ def generate_sensor_for_nonparent_geo(state_groups, res_key, smooth, device, # smoothed test per device if device & smooth: stat, se, sample_size = smoothed_tests_per_device( - devices=state_group["numUniqueDevices_%s"%suffix].values, - tests=state_group['totalTest'].values, + devices=state_group[f"numUniqueDevices_{suffix}"].values, + tests=state_group[f'totalTest_{suffix}'].values, min_obs=MIN_OBS, pool_days=POOL_DAYS) # raw test per device elif device & (not smooth): stat, se, sample_size = raw_tests_per_device( - devices=state_group["numUniqueDevices_s"%suffix].values, - tests=state_group['totalTest'].values, + devices=state_group[f"numUniqueDevices_{suffix}"].values, + tests=state_group[f'totalTest_{suffix}'].values, min_obs=MIN_OBS) # smoothed pct positive elif (not device) & smooth: stat, se, sample_size = smoothed_positive_prop( - tests=state_group['totalTest_%s'%suffix].values, - positives=state_group['positiveTest_%s'%suffix].values, + tests=state_group[f'totalTest_{suffix}'].values, + positives=state_group[f'positiveTest_{suffix}'].values, min_obs=MIN_OBS, pool_days=POOL_DAYS) stat = stat * 100 # raw pct positive else: stat, se, sample_size = raw_positive_prop( - tests=state_group['totalTest_%s'%suffix].values, - positives=state_group['positiveTest_%s'%suffix].values, + tests=state_group[f'totalTest_{suffix}'].values, + positives=state_group[f'positiveTest_{suffix}'].values, min_obs=MIN_OBS) stat = stat * 100 @@ -89,6 +89,8 @@ def generate_sensor_for_parent_geo(state_groups, data, res_key, smooth, """ has_parent = True res_df = pd.DataFrame(columns=["geo_id", "val", "se", "sample_size"]) + if res_key == "fips": # Add rest-of-state report for county level + data = add_megacounties(data, smooth) res_groups = data.groupby(res_key) loc_list = list(res_groups.groups.keys()) for loc in loc_list: @@ -109,41 +111,41 @@ def generate_sensor_for_parent_geo(state_groups, data, res_key, smooth, if has_parent: if device: stat, se, sample_size = smoothed_tests_per_device( - devices=res_group["numUniqueDevices_%s"%suffix].values, - tests=res_group['totalTest_%s'%suffix].values, + devices=res_group[f"numUniqueDevices_{suffix}"].values, + tests=res_group[f'totalTest_{suffix}'].values, min_obs=MIN_OBS, pool_days=POOL_DAYS, - parent_devices=res_group["numUniqueDevices_%s_parent"%suffix].values, - parent_tests=res_group["totalTest_%s_parent"%suffix].values) + parent_devices=res_group[f"numUniqueDevices_{suffix}_parent"].values, + parent_tests=res_group[f"totalTest_{suffix}_parent"].values) else: stat, se, sample_size = smoothed_positive_prop( - tests=res_group['totalTest_%s'%suffix].values, - positives=res_group['positiveTest_%s'%suffix].values, + tests=res_group[f'totalTest_{suffix}'].values, + positives=res_group[f'positiveTest_{suffix}'].values, min_obs=MIN_OBS, pool_days=POOL_DAYS, - parent_tests=res_group["totalTest_%s_parent"%suffix].values, - parent_positives=res_group['positiveTest_%s_parent'%suffix].values) + parent_tests=res_group[f"totalTest_{suffix}_parent"].values, + parent_positives=res_group[f'positiveTest_{suffix}_parent'].values) stat = stat * 100 else: if device: stat, se, sample_size = smoothed_tests_per_device( - devices=res_group["numUniqueDevices_%s"%suffix].values, - tests=res_group['totalTest_%s'%suffix].values, + devices=res_group[f"numUniqueDevices_{suffix}"].values, + tests=res_group[f'totalTest_{suffix}'].values, min_obs=MIN_OBS, pool_days=POOL_DAYS) else: stat, se, sample_size = smoothed_positive_prop( - tests=res_group['totalTest_%s'%suffix].values, - positives=res_group['positiveTest_%s'%suffix].values, + tests=res_group[f'totalTest_{suffix}'].values, + positives=res_group[f'positiveTest_{suffix}'].values, min_obs=MIN_OBS, pool_days=POOL_DAYS) stat = stat * 100 else: if device: stat, se, sample_size = raw_tests_per_device( - devices=res_group["numUniqueDevices_%s"%suffix].values, - tests=res_group['totalTest_%s'%suffix].values, + devices=res_group[f"numUniqueDevices_{suffix}"].values, + tests=res_group[f'totalTest_{suffix}'].values, min_obs=MIN_OBS) else: stat, se, sample_size = raw_positive_prop( - tests=res_group['totalTest_%s'%suffix].values, - positives=res_group['positiveTest_%s'%suffix].values, + tests=res_group[f'totalTest_{suffix}'].values, + positives=res_group[f'positiveTest_{suffix}'].values, min_obs=MIN_OBS) stat = stat * 100 diff --git a/quidel_covidtest/delphi_quidel_covidtest/geo_maps.py b/quidel_covidtest/delphi_quidel_covidtest/geo_maps.py index 33b7c4830..20ebde1c2 100644 --- a/quidel_covidtest/delphi_quidel_covidtest/geo_maps.py +++ b/quidel_covidtest/delphi_quidel_covidtest/geo_maps.py @@ -1,7 +1,13 @@ """Contains geographic mapping tools.""" +from itertools import product +from functools import reduce + +import pandas as pd + from delphi_utils import GeoMapper +from .constants import (AGE_GROUPS, MIN_OBS) -DATA_COLS = ['totalTest', 'numUniqueDevices', 'positiveTest', "population"] +DATA_COLS = ['totalTest', 'numUniqueDevices', 'positiveTest'] GMPR = GeoMapper() # Use geo utils GEO_KEY_DICT = { "county": "fips", @@ -12,8 +18,7 @@ "hhs": "hhs" } - -def geo_map(geo_res, df, agegroup): +def geo_map(geo_res, df): """Map a geocode to a new value.""" data = df.copy() geo_key = GEO_KEY_DICT[geo_res] @@ -21,20 +26,42 @@ def geo_map(geo_res, df, agegroup): data = GMPR.add_population_column(data, "zip") # zip -> geo_res data_cols = [] - for data_col in DATA_COLS: - if data_col != "population": - data_cols.append("_".join([data_col, agegroup])) - else: - data_cols.append(data_col) + for col, agegroup in product(DATA_COLS, AGE_GROUPS): + data_cols.append("_".join([col, agegroup])) + data = GMPR.replace_geocode( data, from_code="zip", new_code=geo_key, date_col = "timestamp", - data_cols=data_cols) + data_cols=data_cols+["population"]) if geo_res in ["state", "hhs", "nation"]: return data, geo_key # Add parent state data = add_parent_state(data, geo_res, geo_key) return data, geo_key +def add_megacounties(data, smooth=False): + """Add megacounties to county level report.""" + assert "fips" in data.columns # Make sure the data is at county level + + # For raw signals, the threshold is MIN_OBS + # For raw signals, the threshold is MIN_OBS/2 + if smooth: + threshold_visits = MIN_OBS/2 + else: + threshold_visits = MIN_OBS + pdList = [] + for agegroup in AGE_GROUPS: + data_cols = [f"{col}_{agegroup}" for col in DATA_COLS] + df = GMPR.fips_to_megacounty(data[data_cols + ["timestamp", "fips"]], + threshold_visits, 1, fips_col="fips", + thr_col=f"totalTest_{agegroup}", + date_col="timestamp") + df.rename({"megafips": "fips"}, axis=1, inplace=True) + megacounties = df[df.fips.str.endswith("000")] + pdList.append(megacounties) + mega_df = reduce(lambda x, y: pd.merge( + x, y, on = ["timestamp", "fips"]), pdList) + + return pd.concat([data, mega_df]) def add_parent_state(data, geo_res, geo_key): """ diff --git a/quidel_covidtest/delphi_quidel_covidtest/pull.py b/quidel_covidtest/delphi_quidel_covidtest/pull.py index eb14b2f21..beb37bbb0 100644 --- a/quidel_covidtest/delphi_quidel_covidtest/pull.py +++ b/quidel_covidtest/delphi_quidel_covidtest/pull.py @@ -185,23 +185,22 @@ def preprocess_new_data(start_date, end_date, params, test_mode, logger): ).merge( overall_pos, on=["timestamp", "zip"], how="left" ).fillna(0).drop_duplicates() - + # Compute Summary info for age groups df["PatientAge"]= df["PatientAge"].fillna(-1) df.loc[df["PatientAge"] == "<1", "PatientAge"] = 0.5 df.loc[df["PatientAge"] == ">85", "PatientAge"] = 100 df["PatientAge"] = df["PatientAge"] .astype(float) + # Should match the suffixes of signal names df["label"] = None - df.loc[df["PatientAge"] < 5, "label"] = "age_0to5" - df.loc[((df["PatientAge"] >= 5)) & (df["PatientAge"] < 14), "label"] = "age_5to13" - df.loc[((df["PatientAge"] >= 14)) & (df["PatientAge"] < 18), "label"] = "age_14to17" + df.loc[df["PatientAge"] < 5, "label"] = "age_0to4" + df.loc[((df["PatientAge"] >= 5)) & (df["PatientAge"] < 18), "label"] = "age_5to17" df.loc[((df["PatientAge"] >= 18)) & (df["PatientAge"] < 50), "label"] = "age_18to49" df.loc[((df["PatientAge"] >= 50)) & (df["PatientAge"] < 65), "label"] = "age_50to64" - df.loc[((df["PatientAge"] >= 65)) & (df["PatientAge"] < 75), "label"] = "age_65to74" - df.loc[df["PatientAge"] >= 75, "label"] = "age_75toOlder" + df.loc[(df["PatientAge"] >= 65), "label"] = "age_65toOlder" df.loc[df["PatientAge"] == -1, "label"] = "NA" - + for agegroup in df["label"].unique(): if agegroup == "NA": continue @@ -212,21 +211,21 @@ def preprocess_new_data(start_date, end_date, params, test_mode, logger): as_index=False)['OverallResult'].count() group_pos["positiveTest_%s"%agegroup] = group_pos["OverallResult"] group_pos.drop(labels="OverallResult", axis="columns", inplace=True) - + # Compute overallTotal group_total = df.loc[df["label"] == agegroup].groupby( by=["timestamp", "zip"], as_index=False)['OverallResult'].count() group_total["totalTest_%s"%agegroup] = group_total["OverallResult"] group_total.drop(labels="OverallResult", axis="columns", inplace=True) - + # Compute numUniqueDevices group_numUniqueDevices = df.loc[df["label"] == agegroup].groupby( by=["timestamp", "zip"], as_index=False)["SofiaSerNum"].agg({"SofiaSerNum": "nunique"}).rename( columns={"SofiaSerNum": "numUniqueDevices_%s"%agegroup} ) - + df_merged = df_merged.merge( group_numUniqueDevices, on=["timestamp", "zip"], how="left" ).merge( diff --git a/quidel_covidtest/delphi_quidel_covidtest/run.py b/quidel_covidtest/delphi_quidel_covidtest/run.py index 4ef95b795..7ff61f9c7 100644 --- a/quidel_covidtest/delphi_quidel_covidtest/run.py +++ b/quidel_covidtest/delphi_quidel_covidtest/run.py @@ -94,43 +94,10 @@ def run_module(params: Dict[str, Any]): wip_signal=params["indicator"]["wip_signal"], prefix="wip_") smoothers = SMOOTHERS.copy() - for agegroup in AGE_GROUPS: - for geo_res in ["state"]:#NONPARENT_GEO_RESOLUTIONS: - geo_data, res_key = geo_map(geo_res, data, agegroup) - geo_groups = geo_data.groupby(res_key) - # for sensor in sensors: - # if agegroup == "total": - # sensor_name = sensor - # else: - # sensor_name = "_".join([sensor, agegroup]) - # logger.info("Generating signal and exporting to CSV", - # geo_res=geo_res, - # sensor=sensor) - # if sensor.endswith(SMOOTHED_POSITIVE): - # smoothers[sensor] = smoothers.pop(SMOOTHED_POSITIVE) - # elif sensor.endswith(RAW_POSITIVE): - # smoothers[sensor] = smoothers.pop(RAW_POSITIVE) - # elif sensor.endswith(SMOOTHED_TEST_PER_DEVICE): - # smoothers[sensor] = smoothers.pop(SMOOTHED_TEST_PER_DEVICE) - # else: - # smoothers[sensor] = smoothers.pop(RAW_TEST_PER_DEVICE) - # state_df = generate_sensor_for_nonparent_geo( - # geo_groups, res_key, smooth=smoothers[sensor][1], - # device=smoothers[sensor][0], first_date=first_date, - # last_date=last_date, suffix=agegroup) - # dates = create_export_csv( - # state_df, - # geo_res=geo_res, - # sensor=sensor_name, - # export_dir=export_dir, - # start_date=export_start_date, - # end_date=export_end_date) - # if len(dates) > 0: - # stats.append((max(dates), len(dates))) - - # County/HRR/MSA level - for geo_res in ["county"]:#PARENT_GEO_RESOLUTIONS: - geo_data, res_key = geo_map(geo_res, data, agegroup) + for geo_res in NONPARENT_GEO_RESOLUTIONS: + geo_data, res_key = geo_map(geo_res, data) + geo_groups = geo_data.groupby(res_key) + for agegroup in AGE_GROUPS: for sensor in sensors: if agegroup == "total": sensor_name = sensor @@ -138,14 +105,48 @@ def run_module(params: Dict[str, Any]): sensor_name = "_".join([sensor, agegroup]) logger.info("Generating signal and exporting to CSV", geo_res=geo_res, - sensor=sensor) + sensor=sensor_name) + if sensor.endswith(SMOOTHED_POSITIVE): + smoothers[sensor] = smoothers.pop(SMOOTHED_POSITIVE) + elif sensor.endswith(RAW_POSITIVE): + smoothers[sensor] = smoothers.pop(RAW_POSITIVE) + elif sensor.endswith(SMOOTHED_TEST_PER_DEVICE): + smoothers[sensor] = smoothers.pop(SMOOTHED_TEST_PER_DEVICE) + else: + smoothers[sensor] = smoothers.pop(RAW_TEST_PER_DEVICE) + state_df = generate_sensor_for_nonparent_geo( + geo_groups, res_key, smooth=smoothers[sensor][1], + device=smoothers[sensor][0], first_date=first_date, + last_date=last_date, suffix=agegroup) + dates = create_export_csv( + state_df, + geo_res=geo_res, + sensor=sensor_name, + export_dir=export_dir, + start_date=export_start_date, + end_date=export_end_date) + if len(dates) > 0: + stats.append((max(dates), len(dates))) + + # County/HRR/MSA level + for geo_res in PARENT_GEO_RESOLUTIONS: + geo_data, res_key = geo_map(geo_res, data) + for agegroup in AGE_GROUPS: + for sensor in sensors: + if agegroup == "total": + sensor_name = sensor + else: + sensor_name = "_".join([sensor, agegroup]) + logger.info("Generating signal and exporting to CSV", + geo_res=geo_res, + sensor=sensor_name) res_df = generate_sensor_for_parent_geo( geo_groups, geo_data, res_key, smooth=smoothers[sensor][1], device=smoothers[sensor][0], first_date=first_date, last_date=last_date, suffix=agegroup) - dates = create_export_csv(res_df, geo_res=geo_res, + dates = create_export_csv(res_df, geo_res=geo_res, sensor=sensor_name, export_dir=export_dir, - start_date=export_start_date, + start_date=export_start_date, end_date=export_end_date, remove_null_samples=True) if len(dates) > 0: From 15f7690e69881f661abd065946c6ed969e831bf7 Mon Sep 17 00:00:00 2001 From: Jingjing Tang Date: Fri, 14 Jan 2022 01:42:19 -0500 Subject: [PATCH 03/31] update unit tests --- quidel_covidtest/tests/test_data/msa_data.csv | 2 +- .../tests/test_data/state_data.csv | 2 +- .../tests/test_data/test_data.csv | 850 +++++++++--------- .../tests/test_generate_sensor.py | 16 +- quidel_covidtest/tests/test_geo_maps.py | 130 ++- quidel_covidtest/tests/test_pull.py | 7 +- 6 files changed, 538 insertions(+), 469 deletions(-) diff --git a/quidel_covidtest/tests/test_data/msa_data.csv b/quidel_covidtest/tests/test_data/msa_data.csv index 39593b937..8ff61dd69 100644 --- a/quidel_covidtest/tests/test_data/msa_data.csv +++ b/quidel_covidtest/tests/test_data/msa_data.csv @@ -1,4 +1,4 @@ -timestamp,cbsa_id,state_id,totalTest,numUniqueDevices,positiveTest +timestamp,cbsa_id,state_id,totalTest_total,numUniqueDevices_total,positiveTest_total 2020-06-14,10580,ny,1,1,0.0 2020-06-14,11100,tx,5,2,0.0 2020-06-14,12020,ga,8,1,0.0 diff --git a/quidel_covidtest/tests/test_data/state_data.csv b/quidel_covidtest/tests/test_data/state_data.csv index 6326c60d3..38e22141c 100644 --- a/quidel_covidtest/tests/test_data/state_data.csv +++ b/quidel_covidtest/tests/test_data/state_data.csv @@ -1,4 +1,4 @@ -timestamp,state_id,totalTest,numUniqueDevices,positiveTest +timestamp,state_id,totalTest_total,numUniqueDevices_total,positiveTest_total 2020-06-14,al,6,2,1.0 2020-06-14,ar,4,1,1.0 2020-06-14,ca,53,6,2.0 diff --git a/quidel_covidtest/tests/test_data/test_data.csv b/quidel_covidtest/tests/test_data/test_data.csv index 8b9d18c4f..f3bdeadc5 100644 --- a/quidel_covidtest/tests/test_data/test_data.csv +++ b/quidel_covidtest/tests/test_data/test_data.csv @@ -1,425 +1,425 @@ -SofiaSerNum,TestDate,Facility,City,State,Zip,PatientAge,Result1,Result2,OverallResult,County,FacilityType,Assay,SCO1,SCO2,CLN,CSN,InstrType,StorageDate,ResultId,SarsTestNumber -1,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,,invalid,,invalid,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,positive,,positive,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,positive,,positive,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,positive,,positive,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,positive,,positive,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,positive,,positive,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,positive,,positive,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,positive,,positive,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,positive,,positive,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,positive,,positive,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,,negative,,negative,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,,invalid,,invalid,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,positive,,positive,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,positive,,positive,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,positive,,positive,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,positive,,positive,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,positive,,positive,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,positive,,positive,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,positive,,positive,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,positive,,positive,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/20/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/20/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/20/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/20/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/20/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/20/20,,Baltimore,MD,21229,,positive,,positive,,,,,,,,,8/17/20,, -3,7/20/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/20/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/20/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -3,7/20/20,,Baltimore,MD,21229,,negative,,negative,,,,,,,,,8/17/20,, -4,7/20/20,,McLean,VA,22101,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/21/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -5,7/21/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -6,7/22/20,,Tampa,FL,33625,,negative,,negative,,,,,,,,,8/17/20,, -6,7/22/20,,Tampa,FL,33625,,positive,,positive,,,,,,,,,8/17/20,, -6,7/22/20,,Tampa,FL,33625,,negative,,negative,,,,,,,,,8/17/20,, -6,7/22/20,,Tampa,FL,33625,,positive,,positive,,,,,,,,,8/17/20,, -6,7/22/20,,Tampa,FL,33625,,negative,,negative,,,,,,,,,8/17/20,, -6,7/22/20,,Tampa,FL,33625,,negative,,negative,,,,,,,,,8/17/20,, -6,7/22/20,,Tampa,FL,33625,,negative,,negative,,,,,,,,,8/17/20,, -6,7/22/20,,Tampa,FL,33625,,negative,,negative,,,,,,,,,8/17/20,, -7,7/22/20,,Columbia,SC,29229,,negative,,negative,,,,,,,,,8/17/20,, -8,7/22/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -8,7/22/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -8,7/22/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -8,7/22/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -8,7/22/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -8,7/22/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -8,7/22/20,,Lorton,VA,22079,,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,,positive,,positive,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,,positive,,positive,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,,positive,,positive,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,,positive,,positive,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,,positive,,positive,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,,negative,,negative,,,,,,,,,8/17/20,, \ No newline at end of file +SofiaSerNum,TestDate,Facility,City,State,Zip,PatientAge,Result1,Result2,OverallResult,County,FacilityType,Assay,SCO1,SCO2,CLN,CSN,InstrType,StorageDate,ResultId,SarsTestNumber +1,7/18/20,,Lorton,VA,22079,21,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,Lorton,VA,22079,23,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,Lorton,VA,22079,27,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,Lorton,VA,22079,13,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,Lorton,VA,22079,68,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,Lorton,VA,22079,56,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,Lorton,VA,22079,82,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,Lorton,VA,22079,6,invalid,,invalid,,,,,,,,,8/17/20,, +1,7/18/20,,Lorton,VA,22079,13,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,Lorton,VA,22079,82,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,Lorton,VA,22079,71,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,Lorton,VA,22079,53,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,Lorton,VA,22079,32,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,Lorton,VA,22079,4,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,Lorton,VA,22079,47,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,Lorton,VA,22079,47,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,Lorton,VA,22079,78,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,Lorton,VA,22079,31,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,Lorton,VA,22079,85,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,Lorton,VA,22079,35,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,Lorton,VA,22079,55,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,Lorton,VA,22079,16,negative,,negative,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,>85,positive,,positive,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,83,negative,,negative,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,39,negative,,negative,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,9,negative,,negative,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,13,negative,,negative,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,77,positive,,positive,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,35,positive,,positive,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,7,negative,,negative,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,76,negative,,negative,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,28,negative,,negative,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,34,positive,,positive,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,13,negative,,negative,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,52,positive,,positive,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,34,negative,,negative,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,61,negative,,negative,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,21,negative,,negative,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,>85,positive,,positive,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,31,positive,,positive,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,67,positive,,positive,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,13,negative,,negative,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,75,positive,,positive,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,74,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,58,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,29,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,60,positive,,positive,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,22,positive,,positive,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,15,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,41,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,43,positive,,positive,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,81,positive,,positive,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,75,positive,,positive,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,40,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,82,positive,,positive,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,59,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,45,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,25,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,59,positive,,positive,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,46,positive,,positive,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,84,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,33,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,24,positive,,positive,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,17,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,78,positive,,positive,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,4,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,70,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,43,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,55,positive,,positive,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,9,positive,,positive,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,22,positive,,positive,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,46,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,66,positive,,positive,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,36,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,46,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,70,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,51,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,5,positive,,positive,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,22,positive,,positive,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,>85,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,12,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,71,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,>85,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,39,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,49,positive,,positive,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,75,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,>85,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,79,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,84,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,72,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,>85,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,10,positive,,positive,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,54,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,31,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,67,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,>85,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,49,positive,,positive,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,>85,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,1,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,>85,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,78,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,56,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,>85,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,>85,positive,,positive,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,5,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,73,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,36,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,66,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,38,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,11,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,>85,positive,,positive,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,42,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,24,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,10,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,74,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,59,positive,,positive,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,11,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,>85,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,77,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,51,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,72,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,>85,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,>85,positive,,positive,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,62,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,31,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,19,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,8,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,30,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,30,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,62,positive,,positive,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,82,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,5,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,>85,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,>85,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,20,positive,,positive,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,8,negative,,negative,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,18,negative,,negative,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,34,negative,,negative,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,25,negative,,negative,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,17,negative,,negative,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,16,negative,,negative,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,39,negative,,negative,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,17,negative,,negative,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,20,negative,,negative,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,79,negative,,negative,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,83,invalid,,invalid,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,27,positive,,positive,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,>85,positive,,positive,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,33,negative,,negative,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,55,negative,,negative,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,39,negative,,negative,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,14,positive,,positive,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,57,negative,,negative,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,5,positive,,positive,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,45,negative,,negative,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,74,negative,,negative,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,44,negative,,negative,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,83,negative,,negative,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,>85,positive,,positive,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,38,positive,,positive,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,39,positive,,positive,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,21,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,58,positive,,positive,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,9,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,48,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,32,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,77,positive,,positive,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,26,positive,,positive,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,50,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,21,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,64,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,40,positive,,positive,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,8,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,55,positive,,positive,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,11,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,7,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,53,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,38,positive,,positive,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,19,positive,,positive,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,82,positive,,positive,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,22,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,50,positive,,positive,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,45,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,52,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,>85,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,39,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,51,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,73,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,28,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,2,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,35,positive,,positive,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,70,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,12,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,7,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,37,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,80,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,8,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,43,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,3,positive,,positive,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,70,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,57,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,38,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,29,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,1,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,2,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,>85,positive,,positive,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,22,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,40,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,59,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,70,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,25,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,74,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,>85,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,41,positive,,positive,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,71,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,29,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,54,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,39,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,15,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,48,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,77,positive,,positive,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,12,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,18,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,59,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,38,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,1,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,73,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,52,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,3,positive,,positive,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,30,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,40,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,77,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,56,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,75,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,73,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,2,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,9,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,44,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,70,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,54,positive,,positive,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,14,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,>85,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,78,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,80,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,56,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,31,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,76,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,84,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,>85,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,>85,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,69,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,79,positive,,positive,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,42,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,22,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,72,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,>85,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,54,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,59,negative,,negative,,,,,,,,,8/17/20,, +3,7/20/20,,Baltimore,MD,21229,63,negative,,negative,,,,,,,,,8/17/20,, +3,7/20/20,,Baltimore,MD,21229,80,negative,,negative,,,,,,,,,8/17/20,, +3,7/20/20,,Baltimore,MD,21229,>85,negative,,negative,,,,,,,,,8/17/20,, +3,7/20/20,,Baltimore,MD,21229,66,negative,,negative,,,,,,,,,8/17/20,, +3,7/20/20,,Baltimore,MD,21229,23,negative,,negative,,,,,,,,,8/17/20,, +3,7/20/20,,Baltimore,MD,21229,61,positive,,positive,,,,,,,,,8/17/20,, +3,7/20/20,,Baltimore,MD,21229,46,negative,,negative,,,,,,,,,8/17/20,, +3,7/20/20,,Baltimore,MD,21229,37,negative,,negative,,,,,,,,,8/17/20,, +3,7/20/20,,Baltimore,MD,21229,57,negative,,negative,,,,,,,,,8/17/20,, +3,7/20/20,,Baltimore,MD,21229,70,negative,,negative,,,,,,,,,8/17/20,, +4,7/20/20,,McLean,VA,22101,73,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,<1,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,54,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,62,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,71,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,16,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,51,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,63,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,66,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,24,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,9,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,2,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,44,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,72,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,31,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,59,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,<1,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,25,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,69,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,23,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,44,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,51,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,37,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,1,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,80,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,49,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,45,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,85,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,16,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,21,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,16,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,80,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,18,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,65,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,76,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,76,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,77,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,29,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,26,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,36,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,21,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,17,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,74,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,>85,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,80,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,61,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,16,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,79,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,1,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,42,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,60,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,62,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,52,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,74,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,2,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,53,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,41,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,66,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,72,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,77,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,38,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,77,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,46,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,42,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,42,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,12,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,75,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,82,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,9,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,58,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,80,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,74,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,58,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,84,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,74,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,67,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,19,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,>85,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,54,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,68,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,1,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,48,negative,,negative,,,,,,,,,8/17/20,, +5,7/21/20,,Lorton,VA,22079,2,negative,,negative,,,,,,,,,8/17/20,, +5,7/21/20,,Lorton,VA,22079,29,negative,,negative,,,,,,,,,8/17/20,, +6,7/22/20,,Tampa,FL,33625,20,negative,,negative,,,,,,,,,8/17/20,, +6,7/22/20,,Tampa,FL,33625,68,positive,,positive,,,,,,,,,8/17/20,, +6,7/22/20,,Tampa,FL,33625,>85,negative,,negative,,,,,,,,,8/17/20,, +6,7/22/20,,Tampa,FL,33625,46,positive,,positive,,,,,,,,,8/17/20,, +6,7/22/20,,Tampa,FL,33625,19,negative,,negative,,,,,,,,,8/17/20,, +6,7/22/20,,Tampa,FL,33625,26,negative,,negative,,,,,,,,,8/17/20,, +6,7/22/20,,Tampa,FL,33625,56,negative,,negative,,,,,,,,,8/17/20,, +6,7/22/20,,Tampa,FL,33625,53,negative,,negative,,,,,,,,,8/17/20,, +7,7/22/20,,Columbia,SC,29229,>85,negative,,negative,,,,,,,,,8/17/20,, +8,7/22/20,,Lorton,VA,22079,69,negative,,negative,,,,,,,,,8/17/20,, +8,7/22/20,,Lorton,VA,22079,76,negative,,negative,,,,,,,,,8/17/20,, +8,7/22/20,,Lorton,VA,22079,58,negative,,negative,,,,,,,,,8/17/20,, +8,7/22/20,,Lorton,VA,22079,66,negative,,negative,,,,,,,,,8/17/20,, +8,7/22/20,,Lorton,VA,22079,19,negative,,negative,,,,,,,,,8/17/20,, +8,7/22/20,,Lorton,VA,22079,70,negative,,negative,,,,,,,,,8/17/20,, +8,7/22/20,,Lorton,VA,22079,50,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,14,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,38,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,72,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,5,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,17,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,35,positive,,positive,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,85,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,47,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,62,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,74,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,4,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,60,positive,,positive,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,81,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,7,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,>85,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,>85,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,66,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,55,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,82,positive,,positive,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,29,positive,,positive,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,25,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,83,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,5,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,>85,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,>85,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,77,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,58,positive,,positive,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,6,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,36,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,24,negative,,negative,,,,,,,,,8/17/20,, diff --git a/quidel_covidtest/tests/test_generate_sensor.py b/quidel_covidtest/tests/test_generate_sensor.py index 0b34919c6..0ef82de83 100644 --- a/quidel_covidtest/tests/test_generate_sensor.py +++ b/quidel_covidtest/tests/test_generate_sensor.py @@ -21,7 +21,9 @@ def test_generate_sensor(self): # raw pct_positive state_pct_positive = generate_sensor_for_nonparent_geo( state_groups, "state_id", smooth = False, device = False, - first_date = datetime(2020, 6, 14), last_date = datetime(2020, 6, 20)) + first_date = datetime(2020, 6, 14), + last_date = datetime(2020, 6, 20), + suffix="total") assert (state_pct_positive.dropna()["val"] < 100).all() assert set(state_pct_positive.columns) ==\ @@ -31,7 +33,9 @@ def test_generate_sensor(self): # raw test_per_device state_test_per_device = generate_sensor_for_nonparent_geo( state_groups, "state_id", smooth = False, device = True, - first_date = datetime(2020, 6, 14), last_date = datetime(2020, 6, 20)) + first_date = datetime(2020, 6, 14), + last_date = datetime(2020, 6, 20), + suffix="total") assert state_test_per_device["se"].isnull().all() assert set(state_test_per_device.columns) ==\ @@ -45,7 +49,9 @@ def test_generate_sensor(self): parse_dates=['timestamp']) msa_pct_positive = generate_sensor_for_parent_geo( state_groups, msa_data, "cbsa_id", smooth = True, device = False, - first_date = datetime(2020, 6, 14), last_date = datetime(2020, 6, 20)) + first_date = datetime(2020, 6, 14), + last_date = datetime(2020, 6, 20), + suffix="total") assert (msa_pct_positive.dropna()["val"] < 100).all() assert set(msa_pct_positive.columns) ==\ @@ -55,7 +61,9 @@ def test_generate_sensor(self): # smoothed test_per_device msa_test_per_device = generate_sensor_for_parent_geo( state_groups, msa_data, "cbsa_id", smooth = True, device = True, - first_date = datetime(2020, 6, 14), last_date = datetime(2020, 6, 20)) + first_date = datetime(2020, 6, 14), + last_date = datetime(2020, 6, 20), + suffix="total") assert msa_test_per_device["se"].isnull().all() assert set(msa_test_per_device.columns) ==\ diff --git a/quidel_covidtest/tests/test_geo_maps.py b/quidel_covidtest/tests/test_geo_maps.py index eb1be3796..fae6933bc 100644 --- a/quidel_covidtest/tests/test_geo_maps.py +++ b/quidel_covidtest/tests/test_geo_maps.py @@ -1,29 +1,52 @@ +from datetime import datetime + import pandas as pd -from delphi_quidel_covidtest.geo_maps import geo_map +from delphi_quidel_covidtest.geo_maps import geo_map, add_megacounties +from delphi_quidel_covidtest.constants import AGE_GROUPS +DATA_COLS = ['totalTest', 'numUniqueDevices', 'positiveTest'] class TestGeoMap: def test_county(self): df = pd.DataFrame( { - "zip": [1607, 1740, 98661, 76010, 76012, 76016], - "timestamp": ["2020-06-15", "2020-06-15", "2020-06-15", - "2020-06-15", "2020-06-15", "2020-06-15"], - "totalTest": [100, 50, 200, 200, 250, 500], - "positiveTest": [10, 8, 15, 5, 20, 50], - "numUniqueDevices": [2, 1, 1, 1, 1, 1] + "zip": [1607, 1740, 1001, 1003, 98661, 76010, 76012, 76016], + "timestamp": ["2020-06-15", "2020-06-15", "2020-06-15", "2020-06-15", + "2020-06-15", "2020-06-15", "2020-06-15", "2020-06-15"], + "totalTest_total": [10, 16, 10, 15, 20, 200, 250, 500], + "positiveTest_total": [6, 8, 6, 8, 5, 5, 20, 50], + "numUniqueDevices_total": [2, 1, 2, 1, 1, 1, 1, 1], } ) + + for agegroup in AGE_GROUPS[1:]: + df[f"totalTest_{agegroup}"] = [2, 3, 2, 2, 4, 40, 20, 25] + df[f"positiveTest_{agegroup}"] = [1, 1, 1, 1, 1, 1, 3, 8] + df[f"numUniqueDevices_{agegroup}"] = [2, 1, 2, 1, 1, 1, 1, 1] new_df, res_key = geo_map("county", df) assert res_key == 'fips' - assert set(new_df["fips"].values) == set(['25027', '53011', '48439']) + assert set(new_df["fips"].values) == set(['25027', '25013', '25015', '53011', '48439']) assert set(new_df["timestamp"].values) == set(df["timestamp"].values) - assert set(new_df["totalTest"].values) == set([150, 200, 950]) - assert set(new_df["positiveTest"].values) == set([18, 15, 75]) + assert set(new_df["totalTest_total"].values) == set([26, 10, 15, 20, 950]) + assert set(new_df["positiveTest_total"].values) == set([14, 6, 8, 5, 75]) + + assert set(new_df["totalTest_age_0to4"].values) == set([5, 2, 2, 85, 4]) + assert set(new_df["positiveTest_age_0to4"].values) == set([2, 1, 1, 12, 1]) + + # Test Megacounties + new_df["timestamp"] = [datetime.strptime(x, "%Y-%m-%d") for x in new_df["timestamp"]] + mega_df = add_megacounties(new_df, True) + + assert set(mega_df["totalTest_total"].values) == set([26, 10, 15, 20, 950, 25, 20]) + assert set(mega_df["positiveTest_total"].values) == set([14, 6, 8, 5, 75, 14, 5]) + + assert set(mega_df["totalTest_age_0to4"].values) == set([5, 2, 2, 85, 4, 4, 9, 4]) + assert set(mega_df["positiveTest_age_0to4"].values) == set([2, 1, 1, 12, 1, 4, 1]) + def test_state(self): @@ -32,18 +55,25 @@ def test_state(self): "zip": [1607, 1740, 98661, 76010, 76012, 76016], "timestamp": ["2020-06-15", "2020-06-15", "2020-06-15", "2020-06-15", "2020-06-15", "2020-06-15"], - "totalTest": [100, 50, 200, 200, 250, 500], - "positiveTest": [10, 8, 15, 5, 20, 50], - "numUniqueDevices": [2, 1, 1, 1, 1, 1] + "totalTest_total": [100, 50, 200, 200, 250, 500], + "positiveTest_total": [10, 8, 15, 5, 20, 50], + "numUniqueDevices_total": [2, 1, 1, 1, 1, 1] } - ) + ) + for agegroup in AGE_GROUPS[1:]: + df[f"totalTest_{agegroup}"] = [20, 10, 20, 40, 20, 25] + df[f"positiveTest_{agegroup}"] = [2, 1, 3, 1, 3, 8] + df[f"numUniqueDevices_{agegroup}"] = [2, 1, 1, 1, 1, 1] new_df, res_key = geo_map("state", df) assert set(new_df["state_id"].values) == set(['ma', 'tx', 'wa']) assert set(new_df["timestamp"].values) == set(df["timestamp"].values) - assert set(new_df["totalTest"].values) == set([150, 200, 950]) - assert set(new_df["positiveTest"].values) == set([18, 15, 75]) + assert set(new_df["totalTest_total"].values) == set([150, 200, 950]) + assert set(new_df["positiveTest_total"].values) == set([18, 15, 75]) + + assert set(new_df["totalTest_age_0to4"].values) == set([30, 85, 20]) + assert set(new_df["positiveTest_age_0to4"].values) == set([3, 12, 3]) def test_hrr(self): @@ -52,18 +82,25 @@ def test_hrr(self): "zip": [1607, 98661, 76010, 76012, 74435, 74936], "timestamp": ["2020-06-15", "2020-06-15", "2020-06-15", "2020-06-15", "2020-06-15", "2020-06-15"], - "totalTest": [100, 50, 200, 200, 250, 500], - "positiveTest": [10, 8, 15, 5, 20, 50], - "numUniqueDevices": [2, 1, 1, 1, 1, 1] + "totalTest_total": [100, 50, 200, 200, 250, 500], + "positiveTest_total": [10, 8, 15, 5, 20, 50], + "numUniqueDevices_total": [2, 1, 1, 1, 1, 1] } ) + for agegroup in AGE_GROUPS[1:]: + df[f"totalTest_{agegroup}"] = [20, 10, 20, 40, 20, 25] + df[f"positiveTest_{agegroup}"] = [2, 1, 3, 1, 3, 8] + df[f"numUniqueDevices_{agegroup}"] = [2, 1, 1, 1, 1, 1] new_df, _ = geo_map("hrr", df) assert set(new_df["hrr"].values) == set(["16", "231", "340", "344", "394"]) assert set(new_df["timestamp"].values) == set(df["timestamp"].values) - assert set(new_df["totalTest"].values) == set([500, 100, 250, 50, 400]) - assert set(new_df["positiveTest"].values) == set([50, 10, 20, 8, 20]) + assert set(new_df["totalTest_total"].values) == set([500, 100, 250, 50, 400]) + assert set(new_df["positiveTest_total"].values) == set([50, 10, 20, 8, 20]) + + assert set(new_df["totalTest_age_0to4"].values) == set([25, 20 ,20, 10, 60]) + assert set(new_df["positiveTest_age_0to4"].values) == set([8, 2, 3, 1, 4]) def test_msa(self): @@ -72,18 +109,25 @@ def test_msa(self): "zip": [1607, 73716, 73719, 76010, 74945, 74936], "timestamp": ["2020-06-15", "2020-06-15", "2020-06-15", "2020-06-15", "2020-06-15", "2020-06-15"], - "totalTest": [100, 50, 200, 200, 250, 500], - "positiveTest": [10, 8, 15, 5, 20, 50], - "numUniqueDevices": [2, 1, 1, 1, 1, 1] + "totalTest_total": [100, 50, 200, 200, 250, 500], + "positiveTest_total": [10, 8, 15, 5, 20, 50], + "numUniqueDevices_total": [2, 1, 1, 1, 1, 1] } ) + for agegroup in AGE_GROUPS[1:]: + df[f"totalTest_{agegroup}"] = [20, 10, 20, 40, 20, 25] + df[f"positiveTest_{agegroup}"] = [2, 1, 3, 1, 3, 8] + df[f"numUniqueDevices_{agegroup}"] = [2, 1, 1, 1, 1, 1] new_df, res_key = geo_map("msa", df) assert set(new_df["msa"].values) == set(['19100', '22900', '49340']) assert set(new_df["timestamp"].values) == set(df["timestamp"].values) - assert set(new_df["totalTest"].values) == set([200, 750, 100]) - assert set(new_df["positiveTest"].values) == set([5, 70, 10]) + assert set(new_df["totalTest_total"].values) == set([200, 750, 100]) + assert set(new_df["positiveTest_total"].values) == set([5, 70, 10]) + + assert set(new_df["totalTest_age_0to4"].values) == set([40, 45, 20]) + assert set(new_df["positiveTest_age_0to4"].values) == set([1, 11, 2]) def test_nation(self): df = pd.DataFrame( @@ -91,18 +135,25 @@ def test_nation(self): "zip": [1607, 73716, 73719, 76010, 74945, 74936], "timestamp": ["2020-06-15", "2020-06-15", "2020-06-15", "2020-06-15", "2020-06-15", "2020-06-15"], - "totalTest": [100, 50, 200, 200, 250, 500], - "positiveTest": [10, 8, 15, 5, 20, 50], - "numUniqueDevices": [2, 1, 1, 1, 1, 1] + "totalTest_total": [100, 50, 200, 200, 250, 500], + "positiveTest_total": [10, 8, 15, 5, 20, 50], + "numUniqueDevices_total": [2, 1, 1, 1, 1, 1] } ) + for agegroup in AGE_GROUPS[1:]: + df[f"totalTest_{agegroup}"] = [20, 10, 20, 40, 20, 25] + df[f"positiveTest_{agegroup}"] = [2, 1, 3, 1, 3, 8] + df[f"numUniqueDevices_{agegroup}"] = [2, 1, 1, 1, 1, 1] new_df, res_key = geo_map("nation", df) assert set(new_df["nation"].values) == set(["us"]) assert set(new_df["timestamp"].values) == set(df["timestamp"].values) - assert set(new_df["totalTest"].values) == set([1300]) - assert set(new_df["positiveTest"].values) == set([108]) + assert set(new_df["totalTest_total"].values) == set([1300]) + assert set(new_df["positiveTest_total"].values) == set([108]) + + assert set(new_df["totalTest_age_0to4"].values) == set([135]) + assert set(new_df["positiveTest_age_0to4"].values) == set([18]) def test_hhs(self): df = pd.DataFrame( @@ -110,15 +161,22 @@ def test_hhs(self): "zip": [1607, 1740, 98661, 76010, 76012, 76016], "timestamp": ["2020-06-15", "2020-06-15", "2020-06-15", "2020-06-15", "2020-06-15", "2020-06-15"], - "totalTest": [100, 50, 200, 200, 250, 500], - "positiveTest": [10, 8, 15, 5, 20, 50], - "numUniqueDevices": [2, 1, 1, 1, 1, 1] + "totalTest_total": [100, 50, 200, 200, 250, 500], + "positiveTest_total": [10, 8, 15, 5, 20, 50], + "numUniqueDevices_total": [2, 1, 1, 1, 1, 1] } ) + for agegroup in AGE_GROUPS[1:]: + df[f"totalTest_{agegroup}"] = [20, 10, 20, 40, 20, 25] + df[f"positiveTest_{agegroup}"] = [2, 1, 3, 1, 3, 8] + df[f"numUniqueDevices_{agegroup}"] = [2, 1, 1, 1, 1, 1] new_df, res_key = geo_map("hhs", df) assert set(new_df["hhs"].values) == set(["1", "6", "10"]) assert set(new_df["timestamp"].values) == set(df["timestamp"].values) - assert set(new_df["totalTest"].values) == set([150, 200, 950]) - assert set(new_df["positiveTest"].values) == set([18, 15, 75]) + assert set(new_df["totalTest_total"].values) == set([150, 200, 950]) + assert set(new_df["positiveTest_total"].values) == set([18, 15, 75]) + + assert set(new_df["totalTest_age_0to4"].values) == set([30, 20, 85]) + assert set(new_df["positiveTest_age_0to4"].values) == set([3, 3, 12]) diff --git a/quidel_covidtest/tests/test_pull.py b/quidel_covidtest/tests/test_pull.py index 17ddbb6fd..ae35fc68f 100644 --- a/quidel_covidtest/tests/test_pull.py +++ b/quidel_covidtest/tests/test_pull.py @@ -11,6 +11,7 @@ check_export_end_date, check_export_start_date ) +from delphi_quidel_covidtest.constants import AGE_GROUPS END_FROM_TODAY_MINUS = 5 EXPORT_DAY_RANGE = 40 @@ -60,8 +61,10 @@ def test_pull_quidel_covidtest(self): assert [first_date.month, first_date.day] == [7, 18] assert [last_date.month, last_date.day] == [7, 23] - assert (df.columns ==\ - ['timestamp', 'zip', 'totalTest', 'numUniqueDevices', 'positiveTest']).all() + assert set(['timestamp', 'zip']).issubset(set(df.columns)) + for agegroup in AGE_GROUPS: + set([f'totalTest_{agegroup}', f'numUniqueDevices_{agegroup}', + f'positiveTest_{agegroup}']).issubset(set(df.columns)) def test_check_intermediate_file(self): From 010491dfcec5772136e7134f7567e4f293a672e6 Mon Sep 17 00:00:00 2001 From: Jingjing Tang Date: Fri, 14 Jan 2022 09:56:45 -0500 Subject: [PATCH 04/31] get smoothers out of the complicated loop --- .../delphi_quidel_covidtest/run.py | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/quidel_covidtest/delphi_quidel_covidtest/run.py b/quidel_covidtest/delphi_quidel_covidtest/run.py index 7ff61f9c7..c224b22a1 100644 --- a/quidel_covidtest/delphi_quidel_covidtest/run.py +++ b/quidel_covidtest/delphi_quidel_covidtest/run.py @@ -40,6 +40,20 @@ def log_exit(start_time, stats, logger): csv_export_count = csv_export_count, max_lag_in_days = max_lag_in_days, oldest_final_export_date = formatted_min_max_date) + +def get_smooth_info(sensors, SMOOTHERS): + """Get smooth info from SMOOTHERS. """ + smoothers = SMOOTHERS.copy() + for sensor in sensors: + if sensor.endswith(SMOOTHED_POSITIVE): + smoothers[sensor] = smoothers.pop(SMOOTHED_POSITIVE) + elif sensor.endswith(RAW_POSITIVE): + smoothers[sensor] = smoothers.pop(RAW_POSITIVE) + elif sensor.endswith(SMOOTHED_TEST_PER_DEVICE): + smoothers[sensor] = smoothers.pop(SMOOTHED_TEST_PER_DEVICE) + else: + smoothers[sensor] = smoothers.pop(RAW_TEST_PER_DEVICE) + return smoothers def run_module(params: Dict[str, Any]): """Run the quidel_covidtest indicator. @@ -92,8 +106,8 @@ def run_module(params: Dict[str, Any]): # Add prefix, if required sensors = add_prefix(SENSORS, wip_signal=params["indicator"]["wip_signal"], - prefix="wip_") - smoothers = SMOOTHERS.copy() + prefix="wip_") + smoothers = get_smooth_info(sensors, SMOOTHERS) for geo_res in NONPARENT_GEO_RESOLUTIONS: geo_data, res_key = geo_map(geo_res, data) geo_groups = geo_data.groupby(res_key) @@ -106,14 +120,6 @@ def run_module(params: Dict[str, Any]): logger.info("Generating signal and exporting to CSV", geo_res=geo_res, sensor=sensor_name) - if sensor.endswith(SMOOTHED_POSITIVE): - smoothers[sensor] = smoothers.pop(SMOOTHED_POSITIVE) - elif sensor.endswith(RAW_POSITIVE): - smoothers[sensor] = smoothers.pop(RAW_POSITIVE) - elif sensor.endswith(SMOOTHED_TEST_PER_DEVICE): - smoothers[sensor] = smoothers.pop(SMOOTHED_TEST_PER_DEVICE) - else: - smoothers[sensor] = smoothers.pop(RAW_TEST_PER_DEVICE) state_df = generate_sensor_for_nonparent_geo( geo_groups, res_key, smooth=smoothers[sensor][1], device=smoothers[sensor][0], first_date=first_date, From d215d6c8e906d19d20a1d13fb1ca26b8a9cc41bb Mon Sep 17 00:00:00 2001 From: Jingjing Tang Date: Fri, 14 Jan 2022 09:58:42 -0500 Subject: [PATCH 05/31] fix a linting --- quidel_covidtest/delphi_quidel_covidtest/run.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/quidel_covidtest/delphi_quidel_covidtest/run.py b/quidel_covidtest/delphi_quidel_covidtest/run.py index c224b22a1..57550d674 100644 --- a/quidel_covidtest/delphi_quidel_covidtest/run.py +++ b/quidel_covidtest/delphi_quidel_covidtest/run.py @@ -40,16 +40,16 @@ def log_exit(start_time, stats, logger): csv_export_count = csv_export_count, max_lag_in_days = max_lag_in_days, oldest_final_export_date = formatted_min_max_date) - -def get_smooth_info(sensors, SMOOTHERS): + +def get_smooth_info(sensors, _SMOOTHERS): """Get smooth info from SMOOTHERS. """ - smoothers = SMOOTHERS.copy() + smoothers = _SMOOTHERS.copy() for sensor in sensors: - if sensor.endswith(SMOOTHED_POSITIVE): - smoothers[sensor] = smoothers.pop(SMOOTHED_POSITIVE) + if sensor.endswith(_SMOOTHED_POSITIVE): + smoothers[sensor] = smoothers.pop(_SMOOTHED_POSITIVE) elif sensor.endswith(RAW_POSITIVE): smoothers[sensor] = smoothers.pop(RAW_POSITIVE) - elif sensor.endswith(SMOOTHED_TEST_PER_DEVICE): + elif sensor.endswith(_SMOOTHED_TEST_PER_DEVICE): smoothers[sensor] = smoothers.pop(SMOOTHED_TEST_PER_DEVICE) else: smoothers[sensor] = smoothers.pop(RAW_TEST_PER_DEVICE) @@ -106,7 +106,7 @@ def run_module(params: Dict[str, Any]): # Add prefix, if required sensors = add_prefix(SENSORS, wip_signal=params["indicator"]["wip_signal"], - prefix="wip_") + prefix="wip_") smoothers = get_smooth_info(sensors, SMOOTHERS) for geo_res in NONPARENT_GEO_RESOLUTIONS: geo_data, res_key = geo_map(geo_res, data) From a120175f463075731fd99748b3a2614ea1fdf120 Mon Sep 17 00:00:00 2001 From: Jingjing Tang Date: Fri, 14 Jan 2022 10:00:15 -0500 Subject: [PATCH 06/31] fix an error --- quidel_covidtest/delphi_quidel_covidtest/run.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/quidel_covidtest/delphi_quidel_covidtest/run.py b/quidel_covidtest/delphi_quidel_covidtest/run.py index 57550d674..e428a9088 100644 --- a/quidel_covidtest/delphi_quidel_covidtest/run.py +++ b/quidel_covidtest/delphi_quidel_covidtest/run.py @@ -45,11 +45,11 @@ def get_smooth_info(sensors, _SMOOTHERS): """Get smooth info from SMOOTHERS. """ smoothers = _SMOOTHERS.copy() for sensor in sensors: - if sensor.endswith(_SMOOTHED_POSITIVE): + if sensor.endswith(SMOOTHED_POSITIVE): smoothers[sensor] = smoothers.pop(_SMOOTHED_POSITIVE) elif sensor.endswith(RAW_POSITIVE): smoothers[sensor] = smoothers.pop(RAW_POSITIVE) - elif sensor.endswith(_SMOOTHED_TEST_PER_DEVICE): + elif sensor.endswith(SMOOTHED_TEST_PER_DEVICE): smoothers[sensor] = smoothers.pop(SMOOTHED_TEST_PER_DEVICE) else: smoothers[sensor] = smoothers.pop(RAW_TEST_PER_DEVICE) From b199cad55dd0df8b66549ca0d788a0f8f24d30f8 Mon Sep 17 00:00:00 2001 From: Jingjing Tang Date: Fri, 14 Jan 2022 10:04:33 -0500 Subject: [PATCH 07/31] ignore too-many-branches in pylintrc --- quidel_covidtest/.pylintrc | 1 + quidel_covidtest/delphi_quidel_covidtest/run.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/quidel_covidtest/.pylintrc b/quidel_covidtest/.pylintrc index 58c6edbba..854cf38d2 100644 --- a/quidel_covidtest/.pylintrc +++ b/quidel_covidtest/.pylintrc @@ -4,6 +4,7 @@ disable=logging-format-interpolation, too-many-locals, too-many-arguments, + too-many-branches, # Allow pytest functions to be part of a class. no-self-use, # Allow pytest classes to have one test. diff --git a/quidel_covidtest/delphi_quidel_covidtest/run.py b/quidel_covidtest/delphi_quidel_covidtest/run.py index e428a9088..45be70edd 100644 --- a/quidel_covidtest/delphi_quidel_covidtest/run.py +++ b/quidel_covidtest/delphi_quidel_covidtest/run.py @@ -46,7 +46,7 @@ def get_smooth_info(sensors, _SMOOTHERS): smoothers = _SMOOTHERS.copy() for sensor in sensors: if sensor.endswith(SMOOTHED_POSITIVE): - smoothers[sensor] = smoothers.pop(_SMOOTHED_POSITIVE) + smoothers[sensor] = smoothers.pop(SMOOTHED_POSITIVE) elif sensor.endswith(RAW_POSITIVE): smoothers[sensor] = smoothers.pop(RAW_POSITIVE) elif sensor.endswith(SMOOTHED_TEST_PER_DEVICE): From e7870e82885c8ed207196cbf3ee03ff6850002dd Mon Sep 17 00:00:00 2001 From: Jingjing Tang Date: Fri, 14 Jan 2022 10:07:56 -0500 Subject: [PATCH 08/31] fix a linting error --- quidel_covidtest/delphi_quidel_covidtest/run.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quidel_covidtest/delphi_quidel_covidtest/run.py b/quidel_covidtest/delphi_quidel_covidtest/run.py index 45be70edd..5823e8e73 100644 --- a/quidel_covidtest/delphi_quidel_covidtest/run.py +++ b/quidel_covidtest/delphi_quidel_covidtest/run.py @@ -42,7 +42,7 @@ def log_exit(start_time, stats, logger): oldest_final_export_date = formatted_min_max_date) def get_smooth_info(sensors, _SMOOTHERS): - """Get smooth info from SMOOTHERS. """ + """Get smooth info from SMOOTHERS.""" smoothers = _SMOOTHERS.copy() for sensor in sensors: if sensor.endswith(SMOOTHED_POSITIVE): From 07642fa6cbe82b66abd010ede9c12c29721534c7 Mon Sep 17 00:00:00 2001 From: Jingjing Tang Date: Fri, 14 Jan 2022 14:10:40 -0500 Subject: [PATCH 09/31] update signal names, add two super age groups --- .../delphi_quidel_covidtest/constants.py | 12 ++++--- .../delphi_quidel_covidtest/pull.py | 36 +++++++++++-------- quidel_covidtest/tests/test_geo_maps.py | 28 +++++++-------- 3 files changed, 42 insertions(+), 34 deletions(-) diff --git a/quidel_covidtest/delphi_quidel_covidtest/constants.py b/quidel_covidtest/delphi_quidel_covidtest/constants.py index af67aa788..f958f023d 100644 --- a/quidel_covidtest/delphi_quidel_covidtest/constants.py +++ b/quidel_covidtest/delphi_quidel_covidtest/constants.py @@ -42,9 +42,11 @@ } AGE_GROUPS = [ "total", - "age_0to4", - "age_5to17", - "age_18to49", - "age_50to64", - "age_65toOlder" + "age_0_4", + "age_5_17", + "age_18_49", + "age_50_64", + "age_65plus", + "age_0_17", + "age_18_64", ] diff --git a/quidel_covidtest/delphi_quidel_covidtest/pull.py b/quidel_covidtest/delphi_quidel_covidtest/pull.py index beb37bbb0..4a074be19 100644 --- a/quidel_covidtest/delphi_quidel_covidtest/pull.py +++ b/quidel_covidtest/delphi_quidel_covidtest/pull.py @@ -8,6 +8,8 @@ import pandas as pd import numpy as np +from .constants import AGE_GROUPS + def get_from_s3(start_date, end_date, bucket, logger): """ Get raw data from aws s3 bucket. @@ -194,36 +196,40 @@ def preprocess_new_data(start_date, end_date, params, test_mode, logger): # Should match the suffixes of signal names df["label"] = None - df.loc[df["PatientAge"] < 5, "label"] = "age_0to4" - df.loc[((df["PatientAge"] >= 5)) & (df["PatientAge"] < 18), "label"] = "age_5to17" - df.loc[((df["PatientAge"] >= 18)) & (df["PatientAge"] < 50), "label"] = "age_18to49" - df.loc[((df["PatientAge"] >= 50)) & (df["PatientAge"] < 65), "label"] = "age_50to64" - df.loc[(df["PatientAge"] >= 65), "label"] = "age_65toOlder" + df.loc[df["PatientAge"] < 5, "label"] = "age_0_4" + df.loc[((df["PatientAge"] >= 5)) & (df["PatientAge"] < 18), "label"] = "age_5_17" + df.loc[((df["PatientAge"] >= 18)) & (df["PatientAge"] < 50), "label"] = "age_18_49" + df.loc[((df["PatientAge"] >= 50)) & (df["PatientAge"] < 65), "label"] = "age_50_64" + df.loc[(df["PatientAge"] >= 65), "label"] = "age_65plus" df.loc[df["PatientAge"] == -1, "label"] = "NA" - - for agegroup in df["label"].unique(): - if agegroup == "NA": - continue + + for agegroup in AGE_GROUPS[1:]: + if agegroup == "age_0_17": + ages = ["age_0_4", "age_5_17"] + elif agegroup == "age_18_64": + ages = ["age_18_49", "age_50_64"] + else: + ages = [agegroup] # Compute overallPositive group_pos = df.loc[(df["OverallResult"] == "positive") - & (df["label"] == agegroup)].groupby( + & (df["label"].isin(ages))].groupby( by=["timestamp", "zip"], as_index=False)['OverallResult'].count() - group_pos["positiveTest_%s"%agegroup] = group_pos["OverallResult"] + group_pos[f"positiveTest_{agegroup}"] = group_pos["OverallResult"] group_pos.drop(labels="OverallResult", axis="columns", inplace=True) # Compute overallTotal - group_total = df.loc[df["label"] == agegroup].groupby( + group_total = df.loc[df["label"].isin(ages)].groupby( by=["timestamp", "zip"], as_index=False)['OverallResult'].count() - group_total["totalTest_%s"%agegroup] = group_total["OverallResult"] + group_total[f"totalTest_{agegroup}"] = group_total["OverallResult"] group_total.drop(labels="OverallResult", axis="columns", inplace=True) # Compute numUniqueDevices - group_numUniqueDevices = df.loc[df["label"] == agegroup].groupby( + group_numUniqueDevices = df.loc[df["label"].isin(ages)].groupby( by=["timestamp", "zip"], as_index=False)["SofiaSerNum"].agg({"SofiaSerNum": "nunique"}).rename( - columns={"SofiaSerNum": "numUniqueDevices_%s"%agegroup} + columns={"SofiaSerNum": f"numUniqueDevices_{agegroup}"} ) df_merged = df_merged.merge( diff --git a/quidel_covidtest/tests/test_geo_maps.py b/quidel_covidtest/tests/test_geo_maps.py index fae6933bc..dc607df3c 100644 --- a/quidel_covidtest/tests/test_geo_maps.py +++ b/quidel_covidtest/tests/test_geo_maps.py @@ -34,8 +34,8 @@ def test_county(self): assert set(new_df["totalTest_total"].values) == set([26, 10, 15, 20, 950]) assert set(new_df["positiveTest_total"].values) == set([14, 6, 8, 5, 75]) - assert set(new_df["totalTest_age_0to4"].values) == set([5, 2, 2, 85, 4]) - assert set(new_df["positiveTest_age_0to4"].values) == set([2, 1, 1, 12, 1]) + assert set(new_df["totalTest_age_0_4"].values) == set([5, 2, 2, 85, 4]) + assert set(new_df["positiveTest_age_0_4"].values) == set([2, 1, 1, 12, 1]) # Test Megacounties new_df["timestamp"] = [datetime.strptime(x, "%Y-%m-%d") for x in new_df["timestamp"]] @@ -44,8 +44,8 @@ def test_county(self): assert set(mega_df["totalTest_total"].values) == set([26, 10, 15, 20, 950, 25, 20]) assert set(mega_df["positiveTest_total"].values) == set([14, 6, 8, 5, 75, 14, 5]) - assert set(mega_df["totalTest_age_0to4"].values) == set([5, 2, 2, 85, 4, 4, 9, 4]) - assert set(mega_df["positiveTest_age_0to4"].values) == set([2, 1, 1, 12, 1, 4, 1]) + assert set(mega_df["totalTest_age_0_4"].values) == set([5, 2, 2, 85, 4, 4, 9, 4]) + assert set(mega_df["positiveTest_age_0_4"].values) == set([2, 1, 1, 12, 1, 4, 1]) def test_state(self): @@ -72,8 +72,8 @@ def test_state(self): assert set(new_df["totalTest_total"].values) == set([150, 200, 950]) assert set(new_df["positiveTest_total"].values) == set([18, 15, 75]) - assert set(new_df["totalTest_age_0to4"].values) == set([30, 85, 20]) - assert set(new_df["positiveTest_age_0to4"].values) == set([3, 12, 3]) + assert set(new_df["totalTest_age_0_4"].values) == set([30, 85, 20]) + assert set(new_df["positiveTest_age_0_4"].values) == set([3, 12, 3]) def test_hrr(self): @@ -99,8 +99,8 @@ def test_hrr(self): assert set(new_df["totalTest_total"].values) == set([500, 100, 250, 50, 400]) assert set(new_df["positiveTest_total"].values) == set([50, 10, 20, 8, 20]) - assert set(new_df["totalTest_age_0to4"].values) == set([25, 20 ,20, 10, 60]) - assert set(new_df["positiveTest_age_0to4"].values) == set([8, 2, 3, 1, 4]) + assert set(new_df["totalTest_age_0_4"].values) == set([25, 20 ,20, 10, 60]) + assert set(new_df["positiveTest_age_0_4"].values) == set([8, 2, 3, 1, 4]) def test_msa(self): @@ -126,8 +126,8 @@ def test_msa(self): assert set(new_df["totalTest_total"].values) == set([200, 750, 100]) assert set(new_df["positiveTest_total"].values) == set([5, 70, 10]) - assert set(new_df["totalTest_age_0to4"].values) == set([40, 45, 20]) - assert set(new_df["positiveTest_age_0to4"].values) == set([1, 11, 2]) + assert set(new_df["totalTest_age_0_4"].values) == set([40, 45, 20]) + assert set(new_df["positiveTest_age_0_4"].values) == set([1, 11, 2]) def test_nation(self): df = pd.DataFrame( @@ -152,8 +152,8 @@ def test_nation(self): assert set(new_df["totalTest_total"].values) == set([1300]) assert set(new_df["positiveTest_total"].values) == set([108]) - assert set(new_df["totalTest_age_0to4"].values) == set([135]) - assert set(new_df["positiveTest_age_0to4"].values) == set([18]) + assert set(new_df["totalTest_age_0_4"].values) == set([135]) + assert set(new_df["positiveTest_age_0_4"].values) == set([18]) def test_hhs(self): df = pd.DataFrame( @@ -178,5 +178,5 @@ def test_hhs(self): assert set(new_df["totalTest_total"].values) == set([150, 200, 950]) assert set(new_df["positiveTest_total"].values) == set([18, 15, 75]) - assert set(new_df["totalTest_age_0to4"].values) == set([30, 20, 85]) - assert set(new_df["positiveTest_age_0to4"].values) == set([3, 3, 12]) + assert set(new_df["totalTest_age_0_4"].values) == set([30, 20, 85]) + assert set(new_df["positiveTest_age_0_4"].values) == set([3, 3, 12]) From 1ee31aed286243ab3495ffc46c36ff6170b2b539 Mon Sep 17 00:00:00 2001 From: Jingjing Tang Date: Fri, 14 Jan 2022 14:13:31 -0500 Subject: [PATCH 10/31] fix a linting error --- quidel_covidtest/delphi_quidel_covidtest/pull.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quidel_covidtest/delphi_quidel_covidtest/pull.py b/quidel_covidtest/delphi_quidel_covidtest/pull.py index 4a074be19..60ff2dd86 100644 --- a/quidel_covidtest/delphi_quidel_covidtest/pull.py +++ b/quidel_covidtest/delphi_quidel_covidtest/pull.py @@ -202,7 +202,7 @@ def preprocess_new_data(start_date, end_date, params, test_mode, logger): df.loc[((df["PatientAge"] >= 50)) & (df["PatientAge"] < 65), "label"] = "age_50_64" df.loc[(df["PatientAge"] >= 65), "label"] = "age_65plus" df.loc[df["PatientAge"] == -1, "label"] = "NA" - + for agegroup in AGE_GROUPS[1:]: if agegroup == "age_0_17": ages = ["age_0_4", "age_5_17"] From 4eee96141f07a595e9515192bbe021a9bd6e4aeb Mon Sep 17 00:00:00 2001 From: Jingjing Tang Date: Tue, 18 Jan 2022 10:20:56 -0500 Subject: [PATCH 11/31] remove 18-64 age group --- quidel_covidtest/delphi_quidel_covidtest/constants.py | 1 - quidel_covidtest/delphi_quidel_covidtest/pull.py | 2 -- 2 files changed, 3 deletions(-) diff --git a/quidel_covidtest/delphi_quidel_covidtest/constants.py b/quidel_covidtest/delphi_quidel_covidtest/constants.py index f958f023d..8e4d37cb2 100644 --- a/quidel_covidtest/delphi_quidel_covidtest/constants.py +++ b/quidel_covidtest/delphi_quidel_covidtest/constants.py @@ -48,5 +48,4 @@ "age_50_64", "age_65plus", "age_0_17", - "age_18_64", ] diff --git a/quidel_covidtest/delphi_quidel_covidtest/pull.py b/quidel_covidtest/delphi_quidel_covidtest/pull.py index 60ff2dd86..a76938a42 100644 --- a/quidel_covidtest/delphi_quidel_covidtest/pull.py +++ b/quidel_covidtest/delphi_quidel_covidtest/pull.py @@ -206,8 +206,6 @@ def preprocess_new_data(start_date, end_date, params, test_mode, logger): for agegroup in AGE_GROUPS[1:]: if agegroup == "age_0_17": ages = ["age_0_4", "age_5_17"] - elif agegroup == "age_18_64": - ages = ["age_18_49", "age_50_64"] else: ages = [agegroup] # Compute overallPositive From a81050c9e534981b0705de5d5cfae9eca4d105c0 Mon Sep 17 00:00:00 2001 From: Jingjing Tang Date: Tue, 18 Jan 2022 11:41:50 -0500 Subject: [PATCH 12/31] add whitespace and add comments --- quidel_covidtest/delphi_quidel_covidtest/pull.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/quidel_covidtest/delphi_quidel_covidtest/pull.py b/quidel_covidtest/delphi_quidel_covidtest/pull.py index a76938a42..d03e13651 100644 --- a/quidel_covidtest/delphi_quidel_covidtest/pull.py +++ b/quidel_covidtest/delphi_quidel_covidtest/pull.py @@ -189,7 +189,7 @@ def preprocess_new_data(start_date, end_date, params, test_mode, logger): ).fillna(0).drop_duplicates() # Compute Summary info for age groups - df["PatientAge"]= df["PatientAge"].fillna(-1) + df["PatientAge"] = df["PatientAge"].fillna(-1) df.loc[df["PatientAge"] == "<1", "PatientAge"] = 0.5 df.loc[df["PatientAge"] == ">85", "PatientAge"] = 100 df["PatientAge"] = df["PatientAge"] .astype(float) @@ -203,7 +203,7 @@ def preprocess_new_data(start_date, end_date, params, test_mode, logger): df.loc[(df["PatientAge"] >= 65), "label"] = "age_65plus" df.loc[df["PatientAge"] == -1, "label"] = "NA" - for agegroup in AGE_GROUPS[1:]: + for agegroup in AGE_GROUPS[1:]: # Exclude total if agegroup == "age_0_17": ages = ["age_0_4", "age_5_17"] else: From dc06d9cf7c58830db811428eaa9c283f333711fd Mon Sep 17 00:00:00 2001 From: Jingjing Tang Date: Tue, 18 Jan 2022 11:53:21 -0500 Subject: [PATCH 13/31] add tests for ages 0-17 --- quidel_covidtest/tests/test_geo_maps.py | 59 ++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 6 deletions(-) diff --git a/quidel_covidtest/tests/test_geo_maps.py b/quidel_covidtest/tests/test_geo_maps.py index dc607df3c..83e828f83 100644 --- a/quidel_covidtest/tests/test_geo_maps.py +++ b/quidel_covidtest/tests/test_geo_maps.py @@ -21,10 +21,14 @@ def test_county(self): } ) - for agegroup in AGE_GROUPS[1:]: + for agegroup in AGE_GROUPS[1:-1]: df[f"totalTest_{agegroup}"] = [2, 3, 2, 2, 4, 40, 20, 25] df[f"positiveTest_{agegroup}"] = [1, 1, 1, 1, 1, 1, 3, 8] df[f"numUniqueDevices_{agegroup}"] = [2, 1, 2, 1, 1, 1, 1, 1] + + df[f"totalTest_age_0_17"] = [4, 6, 4, 4, 8, 80, 40, 50] + df[f"positiveTest_age_0_17"] = [2, 2, 2, 2, 2, 2, 6, 16] + df[f"numUniqueDevices_age_0_17"] = [2, 1, 2, 1, 1, 1, 1, 1] new_df, res_key = geo_map("county", df) @@ -37,6 +41,9 @@ def test_county(self): assert set(new_df["totalTest_age_0_4"].values) == set([5, 2, 2, 85, 4]) assert set(new_df["positiveTest_age_0_4"].values) == set([2, 1, 1, 12, 1]) + assert set(new_df["totalTest_age_0_17"].values) == set([10, 4, 4, 170, 8]) + assert set(new_df["positiveTest_age_0_17"].values) == set([4, 2, 2, 24, 2]) + # Test Megacounties new_df["timestamp"] = [datetime.strptime(x, "%Y-%m-%d") for x in new_df["timestamp"]] mega_df = add_megacounties(new_df, True) @@ -47,6 +54,9 @@ def test_county(self): assert set(mega_df["totalTest_age_0_4"].values) == set([5, 2, 2, 85, 4, 4, 9, 4]) assert set(mega_df["positiveTest_age_0_4"].values) == set([2, 1, 1, 12, 1, 4, 1]) + assert set(mega_df["totalTest_age_0_17"].values) == set([10, 4, 4, 170, 8, 8, 18, 8]) + assert set(mega_df["positiveTest_age_0_17"].values) == set([4, 2, 2, 24, 2, 8, 2]) + def test_state(self): @@ -60,10 +70,15 @@ def test_state(self): "numUniqueDevices_total": [2, 1, 1, 1, 1, 1] } ) - for agegroup in AGE_GROUPS[1:]: + for agegroup in AGE_GROUPS[1:-1]: df[f"totalTest_{agegroup}"] = [20, 10, 20, 40, 20, 25] df[f"positiveTest_{agegroup}"] = [2, 1, 3, 1, 3, 8] df[f"numUniqueDevices_{agegroup}"] = [2, 1, 1, 1, 1, 1] + + df[f"totalTest_age_0_17"] = [40, 20, 40, 80, 40, 50] + df[f"positiveTest_age_0_17"] = [4, 2, 6, 2, 6, 16] + df[f"numUniqueDevices_age_0_17"] = [2, 1, 1, 1, 1, 1] + new_df, res_key = geo_map("state", df) @@ -74,6 +89,9 @@ def test_state(self): assert set(new_df["totalTest_age_0_4"].values) == set([30, 85, 20]) assert set(new_df["positiveTest_age_0_4"].values) == set([3, 12, 3]) + + assert set(new_df["totalTest_age_0_17"].values) == set([60, 170, 40]) + assert set(new_df["positiveTest_age_0_17"].values) == set([6, 24, 6]) def test_hrr(self): @@ -87,10 +105,14 @@ def test_hrr(self): "numUniqueDevices_total": [2, 1, 1, 1, 1, 1] } ) - for agegroup in AGE_GROUPS[1:]: + for agegroup in AGE_GROUPS[1:-1]: df[f"totalTest_{agegroup}"] = [20, 10, 20, 40, 20, 25] df[f"positiveTest_{agegroup}"] = [2, 1, 3, 1, 3, 8] df[f"numUniqueDevices_{agegroup}"] = [2, 1, 1, 1, 1, 1] + + df[f"totalTest_age_0_17"] = [40, 20, 40, 80, 40, 50] + df[f"positiveTest_age_0_17"] = [4, 2, 6, 2, 6, 16] + df[f"numUniqueDevices_age_0_17"] = [2, 1, 1, 1, 1, 1] new_df, _ = geo_map("hrr", df) @@ -101,6 +123,9 @@ def test_hrr(self): assert set(new_df["totalTest_age_0_4"].values) == set([25, 20 ,20, 10, 60]) assert set(new_df["positiveTest_age_0_4"].values) == set([8, 2, 3, 1, 4]) + + assert set(new_df["totalTest_age_0_17"].values) == set([50, 40, 40, 20, 120]) + assert set(new_df["positiveTest_age_0_17"].values) == set([16, 4, 6, 2, 8]) def test_msa(self): @@ -114,10 +139,14 @@ def test_msa(self): "numUniqueDevices_total": [2, 1, 1, 1, 1, 1] } ) - for agegroup in AGE_GROUPS[1:]: + for agegroup in AGE_GROUPS[1:-1]: df[f"totalTest_{agegroup}"] = [20, 10, 20, 40, 20, 25] df[f"positiveTest_{agegroup}"] = [2, 1, 3, 1, 3, 8] df[f"numUniqueDevices_{agegroup}"] = [2, 1, 1, 1, 1, 1] + + df[f"totalTest_age_0_17"] = [40, 20, 40, 80, 40, 50] + df[f"positiveTest_age_0_17"] = [4, 2, 6, 2, 6, 16] + df[f"numUniqueDevices_age_0_17"] = [2, 1, 1, 1, 1, 1] new_df, res_key = geo_map("msa", df) @@ -128,6 +157,9 @@ def test_msa(self): assert set(new_df["totalTest_age_0_4"].values) == set([40, 45, 20]) assert set(new_df["positiveTest_age_0_4"].values) == set([1, 11, 2]) + + assert set(new_df["totalTest_age_0_17"].values) == set([80, 90, 40]) + assert set(new_df["positiveTest_age_0_17"].values) == set([2, 22, 4]) def test_nation(self): df = pd.DataFrame( @@ -140,10 +172,14 @@ def test_nation(self): "numUniqueDevices_total": [2, 1, 1, 1, 1, 1] } ) - for agegroup in AGE_GROUPS[1:]: + for agegroup in AGE_GROUPS[1:-1]: df[f"totalTest_{agegroup}"] = [20, 10, 20, 40, 20, 25] df[f"positiveTest_{agegroup}"] = [2, 1, 3, 1, 3, 8] df[f"numUniqueDevices_{agegroup}"] = [2, 1, 1, 1, 1, 1] + + df[f"totalTest_age_0_17"] = [40, 20, 40, 80, 40, 50] + df[f"positiveTest_age_0_17"] = [4, 2, 6, 2, 6, 16] + df[f"numUniqueDevices_age_0_17"] = [2, 1, 1, 1, 1, 1] new_df, res_key = geo_map("nation", df) @@ -154,6 +190,9 @@ def test_nation(self): assert set(new_df["totalTest_age_0_4"].values) == set([135]) assert set(new_df["positiveTest_age_0_4"].values) == set([18]) + + assert set(new_df["totalTest_age_0_17"].values) == set([270]) + assert set(new_df["positiveTest_age_0_17"].values) == set([36]) def test_hhs(self): df = pd.DataFrame( @@ -166,10 +205,14 @@ def test_hhs(self): "numUniqueDevices_total": [2, 1, 1, 1, 1, 1] } ) - for agegroup in AGE_GROUPS[1:]: + for agegroup in AGE_GROUPS[1:-1]: df[f"totalTest_{agegroup}"] = [20, 10, 20, 40, 20, 25] df[f"positiveTest_{agegroup}"] = [2, 1, 3, 1, 3, 8] df[f"numUniqueDevices_{agegroup}"] = [2, 1, 1, 1, 1, 1] + + df[f"totalTest_age_0_17"] = [40, 20, 40, 80, 40, 50] + df[f"positiveTest_age_0_17"] = [4, 2, 6, 2, 6, 16] + df[f"numUniqueDevices_age_0_17"] = [2, 1, 1, 1, 1, 1] new_df, res_key = geo_map("hhs", df) @@ -180,3 +223,7 @@ def test_hhs(self): assert set(new_df["totalTest_age_0_4"].values) == set([30, 20, 85]) assert set(new_df["positiveTest_age_0_4"].values) == set([3, 3, 12]) + + assert set(new_df["totalTest_age_0_17"].values) == set([60, 40, 170]) + assert set(new_df["positiveTest_age_0_17"].values) == set([6, 6, 24]) + From 0c0f9f5143d3af7c26cc1fd73c722bd06ea8e056 Mon Sep 17 00:00:00 2001 From: Jingjing Tang Date: Tue, 18 Jan 2022 11:56:12 -0500 Subject: [PATCH 14/31] small udpates for suggested changes --- quidel_covidtest/delphi_quidel_covidtest/geo_maps.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/quidel_covidtest/delphi_quidel_covidtest/geo_maps.py b/quidel_covidtest/delphi_quidel_covidtest/geo_maps.py index 20ebde1c2..6d802c5e6 100644 --- a/quidel_covidtest/delphi_quidel_covidtest/geo_maps.py +++ b/quidel_covidtest/delphi_quidel_covidtest/geo_maps.py @@ -25,13 +25,13 @@ def geo_map(geo_res, df): # Add population for each zipcode data = GMPR.add_population_column(data, "zip") # zip -> geo_res - data_cols = [] + data_cols = ["population"] for col, agegroup in product(DATA_COLS, AGE_GROUPS): data_cols.append("_".join([col, agegroup])) data = GMPR.replace_geocode( data, from_code="zip", new_code=geo_key, date_col = "timestamp", - data_cols=data_cols+["population"]) + data_cols=data_cols) if geo_res in ["state", "hhs", "nation"]: return data, geo_key # Add parent state @@ -43,7 +43,7 @@ def add_megacounties(data, smooth=False): assert "fips" in data.columns # Make sure the data is at county level # For raw signals, the threshold is MIN_OBS - # For raw signals, the threshold is MIN_OBS/2 + # For smoothed signals, the threshold is MIN_OBS/2 if smooth: threshold_visits = MIN_OBS/2 else: From 1707cfbdebc3ffa53a9a568fa973fcba48ec12e3 Mon Sep 17 00:00:00 2001 From: Jingjing Tang Date: Fri, 21 Jan 2022 12:44:59 -0500 Subject: [PATCH 15/31] add state_id for megacounties --- quidel_covidtest/delphi_quidel_covidtest/geo_maps.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/quidel_covidtest/delphi_quidel_covidtest/geo_maps.py b/quidel_covidtest/delphi_quidel_covidtest/geo_maps.py index 6d802c5e6..9cefc0f9e 100644 --- a/quidel_covidtest/delphi_quidel_covidtest/geo_maps.py +++ b/quidel_covidtest/delphi_quidel_covidtest/geo_maps.py @@ -60,6 +60,8 @@ def add_megacounties(data, smooth=False): pdList.append(megacounties) mega_df = reduce(lambda x, y: pd.merge( x, y, on = ["timestamp", "fips"]), pdList) + mega_df = GMPR.add_geocode(mega_df, from_code="fips", new_code="state_id", + from_col="fips", new_col="state_id") return pd.concat([data, mega_df]) From e1226e19ddfa95542e0f7bdc78c3e81b45672259 Mon Sep 17 00:00:00 2001 From: Jingjing Tang Date: Fri, 21 Jan 2022 12:45:22 -0500 Subject: [PATCH 16/31] add tests for state_id --- quidel_covidtest/tests/test_geo_maps.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/quidel_covidtest/tests/test_geo_maps.py b/quidel_covidtest/tests/test_geo_maps.py index 83e828f83..b1c74af22 100644 --- a/quidel_covidtest/tests/test_geo_maps.py +++ b/quidel_covidtest/tests/test_geo_maps.py @@ -57,6 +57,8 @@ def test_county(self): assert set(mega_df["totalTest_age_0_17"].values) == set([10, 4, 4, 170, 8, 8, 18, 8]) assert set(mega_df["positiveTest_age_0_17"].values) == set([4, 2, 2, 24, 2, 8, 2]) + assert set(mega_df["state_id"].values) == set(["ma", "tx", "wa"]) + def test_state(self): From 562773d6aab7dbda6c7bb8cea268881163348cde Mon Sep 17 00:00:00 2001 From: Dmitry Shemetov Date: Fri, 21 Jan 2022 14:01:56 -0800 Subject: [PATCH 17/31] Add minimal censored counties test and get error? --- quidel_covidtest/tests/test_data/test_data.csv | 4 ++++ quidel_covidtest/tests/test_run.py | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/quidel_covidtest/tests/test_data/test_data.csv b/quidel_covidtest/tests/test_data/test_data.csv index f3bdeadc5..a7c927d8d 100644 --- a/quidel_covidtest/tests/test_data/test_data.csv +++ b/quidel_covidtest/tests/test_data/test_data.csv @@ -1,4 +1,8 @@ SofiaSerNum,TestDate,Facility,City,State,Zip,PatientAge,Result1,Result2,OverallResult,County,FacilityType,Assay,SCO1,SCO2,CLN,CSN,InstrType,StorageDate,ResultId,SarsTestNumber +1,7/18/20,,TestCity,TestState,24526,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,150,positive,,positive,,,,,,,,,8/17/20,, 1,7/18/20,,Lorton,VA,22079,21,negative,,negative,,,,,,,,,8/17/20,, 1,7/18/20,,Lorton,VA,22079,23,negative,,negative,,,,,,,,,8/17/20,, 1,7/18/20,,Lorton,VA,22079,27,negative,,negative,,,,,,,,,8/17/20,, diff --git a/quidel_covidtest/tests/test_run.py b/quidel_covidtest/tests/test_run.py index 89c59a24f..f506aa0ee 100644 --- a/quidel_covidtest/tests/test_run.py +++ b/quidel_covidtest/tests/test_run.py @@ -68,6 +68,18 @@ def test_output_files(self, clean_receiving_dir): ) assert (df.columns.values == ["geo_id", "val", "se", "sample_size"]).all() + # 7/18/20 in test_data/test_data.csv has: + # - zip 24526 -> fips 51019 with 21 positive counts and 3 negative counts + # - zip 22079 -> fips 51059 with many positive and negative counts + # - zip 24527 -> fips 51143 with 150 positive counts and 3 negative counts + # I think that the following output file should then have + # - fips 51059 for the many counts + # - fips 51000 for the censored 24526 counts + # - fips 51143 for the above-threshold 24527 counts + # But instead, 51019 shows up with the same value as 51143. Is this right or am I missing something? + df = pd.read_csv(join("./receiving", "20200718_county_covid_ag_smoothed_pct_positive.csv")) + assert set(df.geo) == set(["51000", "51059", "51143"]) + # test_intermediate_file flag = None for fname in listdir("./cache"): From ef41f6accf9c2811c0c3cdd006a4f3c30a948351 Mon Sep 17 00:00:00 2001 From: Jingjing Tang Date: Fri, 21 Jan 2022 17:50:21 -0500 Subject: [PATCH 18/31] add suggested changes --- quidel_covidtest/delphi_quidel_covidtest/generate_sensor.py | 5 +---- quidel_covidtest/delphi_quidel_covidtest/run.py | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/quidel_covidtest/delphi_quidel_covidtest/generate_sensor.py b/quidel_covidtest/delphi_quidel_covidtest/generate_sensor.py index f43ed3071..5f44a519b 100644 --- a/quidel_covidtest/delphi_quidel_covidtest/generate_sensor.py +++ b/quidel_covidtest/delphi_quidel_covidtest/generate_sensor.py @@ -91,10 +91,7 @@ def generate_sensor_for_parent_geo(state_groups, data, res_key, smooth, res_df = pd.DataFrame(columns=["geo_id", "val", "se", "sample_size"]) if res_key == "fips": # Add rest-of-state report for county level data = add_megacounties(data, smooth) - res_groups = data.groupby(res_key) - loc_list = list(res_groups.groups.keys()) - for loc in loc_list: - res_group = res_groups.get_group(loc) + for loc, res_group in data.groupby(res_key): parent_state = res_group['state_id'].values[0] try: parent_group = state_groups.get_group(parent_state) diff --git a/quidel_covidtest/delphi_quidel_covidtest/run.py b/quidel_covidtest/delphi_quidel_covidtest/run.py index 5823e8e73..fb1a69ac2 100644 --- a/quidel_covidtest/delphi_quidel_covidtest/run.py +++ b/quidel_covidtest/delphi_quidel_covidtest/run.py @@ -133,7 +133,7 @@ def run_module(params: Dict[str, Any]): end_date=export_end_date) if len(dates) > 0: stats.append((max(dates), len(dates))) - + assert geo_res == "state" # Make sure geo_groups is for state level # County/HRR/MSA level for geo_res in PARENT_GEO_RESOLUTIONS: geo_data, res_key = geo_map(geo_res, data) From c81298ba7bb07d357ff29d7ede429e9ba9fdb675 Mon Sep 17 00:00:00 2001 From: Jingjing Tang Date: Sun, 23 Jan 2022 00:24:56 -0500 Subject: [PATCH 19/31] update unit tests based on the current strategy --- quidel_covidtest/tests/test_run.py | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/quidel_covidtest/tests/test_run.py b/quidel_covidtest/tests/test_run.py index f506aa0ee..5c8938307 100644 --- a/quidel_covidtest/tests/test_run.py +++ b/quidel_covidtest/tests/test_run.py @@ -68,17 +68,8 @@ def test_output_files(self, clean_receiving_dir): ) assert (df.columns.values == ["geo_id", "val", "se", "sample_size"]).all() - # 7/18/20 in test_data/test_data.csv has: - # - zip 24526 -> fips 51019 with 21 positive counts and 3 negative counts - # - zip 22079 -> fips 51059 with many positive and negative counts - # - zip 24527 -> fips 51143 with 150 positive counts and 3 negative counts - # I think that the following output file should then have - # - fips 51059 for the many counts - # - fips 51000 for the censored 24526 counts - # - fips 51143 for the above-threshold 24527 counts - # But instead, 51019 shows up with the same value as 51143. Is this right or am I missing something? df = pd.read_csv(join("./receiving", "20200718_county_covid_ag_smoothed_pct_positive.csv")) - assert set(df.geo) == set(["51000", "51059", "51143"]) + assert set(df.geo_id) == set(["51000", "51059", "51143", "51019"]) # test_intermediate_file flag = None From 7721290b173c4e1e0b4335ef103bdd43ba6a3fce Mon Sep 17 00:00:00 2001 From: Jingjing Tang Date: Sun, 23 Jan 2022 00:30:27 -0500 Subject: [PATCH 20/31] geo_id should be integers in the unit tests --- quidel_covidtest/tests/test_run.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quidel_covidtest/tests/test_run.py b/quidel_covidtest/tests/test_run.py index 5c8938307..85c5b611e 100644 --- a/quidel_covidtest/tests/test_run.py +++ b/quidel_covidtest/tests/test_run.py @@ -69,7 +69,7 @@ def test_output_files(self, clean_receiving_dir): assert (df.columns.values == ["geo_id", "val", "se", "sample_size"]).all() df = pd.read_csv(join("./receiving", "20200718_county_covid_ag_smoothed_pct_positive.csv")) - assert set(df.geo_id) == set(["51000", "51059", "51143", "51019"]) + assert set(df.geo_id) == set([51000, 51059, 51143, 51019]) # test_intermediate_file flag = None From b7f94c98ed4d1fc6e2b605cec96fbe4ce78c93fe Mon Sep 17 00:00:00 2001 From: Jingjing Tang Date: Tue, 25 Jan 2022 03:06:30 -0500 Subject: [PATCH 21/31] udpate geographical pooling --- .../delphi_quidel_covidtest/data_tools.py | 20 ++++++++++--------- .../delphi_quidel_covidtest/pull.py | 2 +- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/quidel_covidtest/delphi_quidel_covidtest/data_tools.py b/quidel_covidtest/delphi_quidel_covidtest/data_tools.py index f89a353ed..717a2424f 100644 --- a/quidel_covidtest/delphi_quidel_covidtest/data_tools.py +++ b/quidel_covidtest/delphi_quidel_covidtest/data_tools.py @@ -67,15 +67,14 @@ def _slide_window_sum(arr, k): sarr = np.convolve(temp, np.ones(k, dtype=int), 'valid') return sarr - def _geographical_pooling(tpooled_tests, tpooled_ptests, min_obs): """ Determine how many samples from the parent geography must be borrowed. - If there are no samples available in the parent, the borrow_prop is 0. If - the parent does not have enough samples, we return a borrow_prop of 1, and - the fact that the pooled samples are insufficient are handled in the - statistic fitting step. + If there are no samples available in the parent, the borrow_prop is 0. + If the parent does not have enough samples, we return a borrow_prop of 1. + No more samples borrowed from the parent compared to the number of samples + we currently have. Args: tpooled_tests: np.ndarray[float] @@ -93,10 +92,12 @@ def _geographical_pooling(tpooled_tests, tpooled_ptests, min_obs): """ if (np.any(np.isnan(tpooled_tests)) or np.any(np.isnan(tpooled_ptests))): raise ValueError('[parent] tests should be non-negative ' - 'with no np.nan') + 'with no np.nan') # STEP 1: "TOP UP" USING PARENT LOCATION # Number of observations we need to borrow to "top up" + # Can't borrow more than total no. observations. borrow_tests = np.maximum(min_obs - tpooled_tests, 0) + borrow_tests = np.minimum(borrow_tests, tpooled_tests) # There are many cases (a, b > 0): # Case 1: a / b => no problem # Case 2: a / 0 => np.inf => borrow_prop becomes 1 @@ -108,13 +109,14 @@ def _geographical_pooling(tpooled_tests, tpooled_ptests, min_obs): with np.errstate(divide='ignore', invalid='ignore'): borrow_prop = borrow_tests / tpooled_ptests # If there's nothing to borrow, then ya can't borrow - borrow_prop[np.isnan(borrow_prop)] = 0 - # Can't borrow more than total no. observations. + borrow_prop[(np.isnan(borrow_prop)) + | (tpooled_tests == 0) + | (tpooled_ptests == 0)] = 0 + # Can't borrow more than total no. observations in the parent state # Relies on the fact that np.inf > 1 borrow_prop[borrow_prop > 1] = 1 return borrow_prop - def raw_positive_prop(positives, tests, min_obs): """ Calculate the proportion of positive tests without any temporal smoothing. diff --git a/quidel_covidtest/delphi_quidel_covidtest/pull.py b/quidel_covidtest/delphi_quidel_covidtest/pull.py index d03e13651..ab397ce47 100644 --- a/quidel_covidtest/delphi_quidel_covidtest/pull.py +++ b/quidel_covidtest/delphi_quidel_covidtest/pull.py @@ -346,7 +346,7 @@ def check_export_start_date(export_start_date, export_end_date, export_start_date = datetime(2020, 5, 26) else: export_start_date = datetime.strptime(export_start_date, '%Y-%m-%d') - # Only export data from -45 days to -5 days + # Only export data from -50 days to -5 days if (export_end_date - export_start_date).days > export_day_range: export_start_date = export_end_date - timedelta(days=export_day_range) From 1fdbe49365ab40980125349a928ba6aefcac010a Mon Sep 17 00:00:00 2001 From: Jingjing Tang Date: Tue, 25 Jan 2022 03:07:07 -0500 Subject: [PATCH 22/31] update unit tests --- .../tests/test_data/test_data.csv | 864 +++++++++--------- quidel_covidtest/tests/test_data_tools.py | 17 +- 2 files changed, 448 insertions(+), 433 deletions(-) diff --git a/quidel_covidtest/tests/test_data/test_data.csv b/quidel_covidtest/tests/test_data/test_data.csv index a7c927d8d..cc4c4ee8b 100644 --- a/quidel_covidtest/tests/test_data/test_data.csv +++ b/quidel_covidtest/tests/test_data/test_data.csv @@ -1,429 +1,435 @@ -SofiaSerNum,TestDate,Facility,City,State,Zip,PatientAge,Result1,Result2,OverallResult,County,FacilityType,Assay,SCO1,SCO2,CLN,CSN,InstrType,StorageDate,ResultId,SarsTestNumber -1,7/18/20,,TestCity,TestState,24526,3,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,TestCity,TestState,24526,21,positive,,positive,,,,,,,,,8/17/20,, -1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,TestCity,TestState,24527,150,positive,,positive,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,21,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,23,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,27,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,13,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,68,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,56,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,82,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,6,invalid,,invalid,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,13,positive,,positive,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,82,positive,,positive,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,71,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,53,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,32,positive,,positive,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,4,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,47,positive,,positive,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,47,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,78,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,31,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,85,positive,,positive,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,35,positive,,positive,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,55,positive,,positive,,,,,,,,,8/17/20,, -1,7/18/20,,Lorton,VA,22079,16,negative,,negative,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,>85,positive,,positive,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,83,negative,,negative,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,39,negative,,negative,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,9,negative,,negative,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,13,negative,,negative,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,77,positive,,positive,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,35,positive,,positive,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,7,negative,,negative,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,76,negative,,negative,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,28,negative,,negative,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,34,positive,,positive,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,13,negative,,negative,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,52,positive,,positive,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,34,negative,,negative,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,61,negative,,negative,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,21,negative,,negative,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,>85,positive,,positive,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,31,positive,,positive,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,67,positive,,positive,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,13,negative,,negative,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,75,positive,,positive,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, -2,7/18/20,,Lorton,VA,22079,74,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,58,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,29,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,60,positive,,positive,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,22,positive,,positive,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,15,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,41,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,43,positive,,positive,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,81,positive,,positive,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,75,positive,,positive,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,40,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,82,positive,,positive,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,59,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,45,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,25,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,59,positive,,positive,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,46,positive,,positive,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,84,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,33,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,24,positive,,positive,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,17,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,78,positive,,positive,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,4,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,70,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,43,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,55,positive,,positive,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,9,positive,,positive,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,22,positive,,positive,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,46,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,66,positive,,positive,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,36,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,46,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,70,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,51,negative,,negative,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,5,positive,,positive,,,,,,,,,8/17/20,, -3,7/18/20,,Lorton,VA,22079,22,positive,,positive,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,>85,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,12,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,71,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,>85,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,39,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,49,positive,,positive,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,75,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,>85,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,79,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,84,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,72,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,>85,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,10,positive,,positive,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,54,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,31,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,67,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,>85,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,49,positive,,positive,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,>85,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,1,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,>85,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,78,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,56,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,>85,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,>85,positive,,positive,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,5,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,73,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,36,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,66,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,38,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,11,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,>85,positive,,positive,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,42,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,24,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,10,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,74,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,59,positive,,positive,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,11,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,>85,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,77,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,51,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,72,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,>85,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,>85,positive,,positive,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,62,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,31,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,19,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,8,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,30,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,30,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,62,positive,,positive,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,82,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,5,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,>85,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,>85,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,20,positive,,positive,,,,,,,,,8/17/20,, -2,7/19/20,,Santa Rosa Beach,FL,32459,8,negative,,negative,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,18,negative,,negative,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,34,negative,,negative,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,25,negative,,negative,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,17,negative,,negative,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,16,negative,,negative,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,39,negative,,negative,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,17,negative,,negative,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,20,negative,,negative,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,79,negative,,negative,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,83,invalid,,invalid,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,27,positive,,positive,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,>85,positive,,positive,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,33,negative,,negative,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,55,negative,,negative,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,39,negative,,negative,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,14,positive,,positive,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,57,negative,,negative,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,5,positive,,positive,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,45,negative,,negative,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,74,negative,,negative,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,44,negative,,negative,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,83,negative,,negative,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,>85,positive,,positive,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,38,positive,,positive,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,39,positive,,positive,,,,,,,,,8/17/20,, -1,7/19/20,,Lorton,VA,22079,21,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,58,positive,,positive,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,9,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,48,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,32,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,77,positive,,positive,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,26,positive,,positive,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,50,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,21,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,64,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,40,positive,,positive,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,8,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,55,positive,,positive,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,11,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,7,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,53,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,38,positive,,positive,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,19,positive,,positive,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,82,positive,,positive,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,22,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,50,positive,,positive,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,45,negative,,negative,,,,,,,,,8/17/20,, -2,7/19/20,,Lorton,VA,22079,52,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,>85,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,39,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,51,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,73,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,28,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,2,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,35,positive,,positive,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,70,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,12,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,7,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,37,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,80,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,8,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,43,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,3,positive,,positive,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,70,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,57,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,38,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,29,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,1,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,2,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,>85,positive,,positive,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,22,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,40,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,59,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,70,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,25,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,74,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,>85,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,41,positive,,positive,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,71,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,29,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,54,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,39,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,15,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,48,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,77,positive,,positive,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,12,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,18,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,59,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,38,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,1,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,73,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,52,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,3,positive,,positive,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,30,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,40,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,77,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,56,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,75,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,73,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,2,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,9,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,44,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,70,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,54,positive,,positive,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,14,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,>85,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,78,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,80,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,56,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,31,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,76,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,84,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,>85,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,>85,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,69,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,79,positive,,positive,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,42,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,22,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,72,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,>85,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,54,negative,,negative,,,,,,,,,8/17/20,, -3,7/19/20,,Baltimore,MD,21229,59,negative,,negative,,,,,,,,,8/17/20,, -3,7/20/20,,Baltimore,MD,21229,63,negative,,negative,,,,,,,,,8/17/20,, -3,7/20/20,,Baltimore,MD,21229,80,negative,,negative,,,,,,,,,8/17/20,, -3,7/20/20,,Baltimore,MD,21229,>85,negative,,negative,,,,,,,,,8/17/20,, -3,7/20/20,,Baltimore,MD,21229,66,negative,,negative,,,,,,,,,8/17/20,, -3,7/20/20,,Baltimore,MD,21229,23,negative,,negative,,,,,,,,,8/17/20,, -3,7/20/20,,Baltimore,MD,21229,61,positive,,positive,,,,,,,,,8/17/20,, -3,7/20/20,,Baltimore,MD,21229,46,negative,,negative,,,,,,,,,8/17/20,, -3,7/20/20,,Baltimore,MD,21229,37,negative,,negative,,,,,,,,,8/17/20,, -3,7/20/20,,Baltimore,MD,21229,57,negative,,negative,,,,,,,,,8/17/20,, -3,7/20/20,,Baltimore,MD,21229,70,negative,,negative,,,,,,,,,8/17/20,, -4,7/20/20,,McLean,VA,22101,73,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,<1,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,54,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,62,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,71,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,16,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,51,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,63,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,66,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,24,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,9,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,2,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,44,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,72,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,31,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,59,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,<1,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,25,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,69,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,23,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,44,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,51,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,37,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,1,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,80,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,49,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,45,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,85,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,16,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,21,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,16,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,80,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,18,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,65,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,76,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,76,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,77,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,29,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,26,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,36,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,21,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,17,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,74,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,>85,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,80,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,61,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,16,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,79,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,1,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,42,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,60,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,62,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,52,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,74,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,2,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,53,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,41,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,66,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,72,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,77,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,38,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,77,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,46,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,42,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,42,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,12,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,75,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,82,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,9,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,58,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,80,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,74,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,58,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,84,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,74,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,67,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,19,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,>85,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,54,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,68,negative,,negative,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,1,positive,,positive,,,,,,,,,8/17/20,, -5,7/20/20,,Lorton,VA,22079,48,negative,,negative,,,,,,,,,8/17/20,, -5,7/21/20,,Lorton,VA,22079,2,negative,,negative,,,,,,,,,8/17/20,, -5,7/21/20,,Lorton,VA,22079,29,negative,,negative,,,,,,,,,8/17/20,, -6,7/22/20,,Tampa,FL,33625,20,negative,,negative,,,,,,,,,8/17/20,, -6,7/22/20,,Tampa,FL,33625,68,positive,,positive,,,,,,,,,8/17/20,, -6,7/22/20,,Tampa,FL,33625,>85,negative,,negative,,,,,,,,,8/17/20,, -6,7/22/20,,Tampa,FL,33625,46,positive,,positive,,,,,,,,,8/17/20,, -6,7/22/20,,Tampa,FL,33625,19,negative,,negative,,,,,,,,,8/17/20,, -6,7/22/20,,Tampa,FL,33625,26,negative,,negative,,,,,,,,,8/17/20,, -6,7/22/20,,Tampa,FL,33625,56,negative,,negative,,,,,,,,,8/17/20,, -6,7/22/20,,Tampa,FL,33625,53,negative,,negative,,,,,,,,,8/17/20,, -7,7/22/20,,Columbia,SC,29229,>85,negative,,negative,,,,,,,,,8/17/20,, -8,7/22/20,,Lorton,VA,22079,69,negative,,negative,,,,,,,,,8/17/20,, -8,7/22/20,,Lorton,VA,22079,76,negative,,negative,,,,,,,,,8/17/20,, -8,7/22/20,,Lorton,VA,22079,58,negative,,negative,,,,,,,,,8/17/20,, -8,7/22/20,,Lorton,VA,22079,66,negative,,negative,,,,,,,,,8/17/20,, -8,7/22/20,,Lorton,VA,22079,19,negative,,negative,,,,,,,,,8/17/20,, -8,7/22/20,,Lorton,VA,22079,70,negative,,negative,,,,,,,,,8/17/20,, -8,7/22/20,,Lorton,VA,22079,50,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,14,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,38,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,72,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,5,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,17,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,35,positive,,positive,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,85,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,47,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,62,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,74,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,4,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,60,positive,,positive,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,81,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,7,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,>85,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,>85,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,66,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,55,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,82,positive,,positive,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,29,positive,,positive,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,25,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,83,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,5,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,>85,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,>85,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,77,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,58,positive,,positive,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,6,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,36,negative,,negative,,,,,,,,,8/17/20,, -9,7/23/20,,Tampa,FL,33625,24,negative,,negative,,,,,,,,,8/17/20,, +SofiaSerNum,TestDate,Facility,City,State,Zip,PatientAge,Result1,Result2,OverallResult,County,FacilityType,Assay,SCO1,SCO2,CLN,CSN,InstrType,StorageDate,ResultId,SarsTestNumber +2,7/18/20,,Lorton,VA,22079,39,negative,,negative,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,9,negative,,negative,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,13,negative,,negative,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,77,positive,,positive,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,35,positive,,positive,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,7,negative,,negative,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,76,negative,,negative,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,28,negative,,negative,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,34,positive,,positive,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,13,negative,,negative,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,52,positive,,positive,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,34,negative,,negative,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,61,negative,,negative,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,21,negative,,negative,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,>85,positive,,positive,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,31,positive,,positive,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,67,positive,,positive,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,13,negative,,negative,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,75,positive,,positive,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +2,7/18/20,,Lorton,VA,22079,74,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,58,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,29,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,60,positive,,positive,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,22,positive,,positive,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,15,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,41,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,43,positive,,positive,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,81,positive,,positive,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,75,positive,,positive,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,40,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,82,positive,,positive,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,59,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,45,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,25,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,59,positive,,positive,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,46,positive,,positive,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,84,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,33,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,24,positive,,positive,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,17,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,78,positive,,positive,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,4,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,70,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,43,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,55,positive,,positive,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,9,positive,,positive,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,22,positive,,positive,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,46,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,66,positive,,positive,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,36,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,46,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,70,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,51,negative,,negative,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,5,positive,,positive,,,,,,,,,8/17/20,, +3,7/18/20,,Lorton,VA,22079,22,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,150,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,150,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,150,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,150,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,150,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,150,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,150,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,150,positive,,positive,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,>85,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,39,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,51,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,73,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,28,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,2,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,35,positive,,positive,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,70,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,12,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,7,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,37,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,80,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,8,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,43,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,3,positive,,positive,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,70,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,57,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,38,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,29,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,1,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,2,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,>85,positive,,positive,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,22,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,40,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,59,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,70,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,25,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,74,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,>85,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,41,positive,,positive,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,71,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,29,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,54,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,39,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,15,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,48,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,77,positive,,positive,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,12,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,18,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,59,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,38,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,1,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,73,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,52,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,3,positive,,positive,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,30,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,40,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,77,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,56,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,75,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,73,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,2,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,9,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,44,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,70,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,54,positive,,positive,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,14,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,>85,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,78,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,80,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,56,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,31,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,76,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,84,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,>85,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,>85,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,69,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,79,positive,,positive,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,42,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,22,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,72,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,>85,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,54,negative,,negative,,,,,,,,,8/17/20,, +3,7/19/20,,Baltimore,MD,21229,59,negative,,negative,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,18,negative,,negative,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,34,negative,,negative,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,25,negative,,negative,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,17,negative,,negative,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,16,negative,,negative,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,39,negative,,negative,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,17,negative,,negative,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,20,negative,,negative,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,79,negative,,negative,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,83,invalid,,invalid,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,27,positive,,positive,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,>85,positive,,positive,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,33,negative,,negative,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,55,negative,,negative,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,39,negative,,negative,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,14,positive,,positive,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,57,negative,,negative,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,5,positive,,positive,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,45,negative,,negative,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,74,negative,,negative,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,44,negative,,negative,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,83,negative,,negative,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,>85,positive,,positive,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,38,positive,,positive,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,39,positive,,positive,,,,,,,,,8/17/20,, +1,7/19/20,,Lorton,VA,22079,21,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,58,positive,,positive,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,9,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,48,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,32,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,77,positive,,positive,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,26,positive,,positive,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,50,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,21,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,64,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,40,positive,,positive,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,8,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,55,positive,,positive,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,11,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,7,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,53,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,38,positive,,positive,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,19,positive,,positive,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,82,positive,,positive,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,22,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,50,positive,,positive,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,45,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Lorton,VA,22079,52,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,>85,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,12,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,71,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,>85,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,39,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,49,positive,,positive,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,75,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,>85,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,79,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,84,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,72,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,>85,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,10,positive,,positive,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,54,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,31,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,67,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,>85,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,49,positive,,positive,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,>85,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,1,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,>85,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,78,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,56,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,>85,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,>85,positive,,positive,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,5,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,73,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,36,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,66,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,38,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,11,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,>85,positive,,positive,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,42,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,24,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,10,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,74,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,59,positive,,positive,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,11,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,>85,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,77,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,51,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,72,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,>85,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,>85,positive,,positive,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,62,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,31,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,19,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,8,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,30,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,30,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,62,positive,,positive,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,82,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,5,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,>85,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,>85,negative,,negative,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,20,positive,,positive,,,,,,,,,8/17/20,, +2,7/19/20,,Santa Rosa Beach,FL,32459,8,negative,,negative,,,,,,,,,8/17/20,, +3,7/20/20,,Baltimore,MD,21229,63,negative,,negative,,,,,,,,,8/17/20,, +3,7/20/20,,Baltimore,MD,21229,80,negative,,negative,,,,,,,,,8/17/20,, +3,7/20/20,,Baltimore,MD,21229,>85,negative,,negative,,,,,,,,,8/17/20,, +3,7/20/20,,Baltimore,MD,21229,66,negative,,negative,,,,,,,,,8/17/20,, +3,7/20/20,,Baltimore,MD,21229,23,negative,,negative,,,,,,,,,8/17/20,, +3,7/20/20,,Baltimore,MD,21229,61,positive,,positive,,,,,,,,,8/17/20,, +3,7/20/20,,Baltimore,MD,21229,46,negative,,negative,,,,,,,,,8/17/20,, +3,7/20/20,,Baltimore,MD,21229,37,negative,,negative,,,,,,,,,8/17/20,, +3,7/20/20,,Baltimore,MD,21229,57,negative,,negative,,,,,,,,,8/17/20,, +3,7/20/20,,Baltimore,MD,21229,70,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,<1,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,54,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,62,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,71,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,16,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,51,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,63,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,66,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,24,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,9,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,2,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,44,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,72,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,31,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,59,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,<1,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,25,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,69,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,23,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,44,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,51,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,37,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,1,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,80,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,49,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,45,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,85,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,16,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,21,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,16,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,80,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,18,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,65,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,76,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,76,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,77,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,29,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,26,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,36,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,21,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,17,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,74,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,>85,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,80,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,61,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,16,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,79,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,1,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,42,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,60,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,62,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,52,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,74,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,2,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,53,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,41,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,66,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,72,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,77,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,38,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,77,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,46,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,42,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,42,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,12,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,75,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,82,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,9,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,58,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,80,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,74,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,58,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,84,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,74,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,67,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,19,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,>85,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,>85,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,54,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,68,negative,,negative,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,1,positive,,positive,,,,,,,,,8/17/20,, +5,7/20/20,,Lorton,VA,22079,48,negative,,negative,,,,,,,,,8/17/20,, +4,7/20/20,,McLean,VA,22101,73,negative,,negative,,,,,,,,,8/17/20,, +5,7/21/20,,Lorton,VA,22079,2,negative,,negative,,,,,,,,,8/17/20,, +5,7/21/20,,Lorton,VA,22079,29,negative,,negative,,,,,,,,,8/17/20,, +8,7/22/20,,Lorton,VA,22079,69,negative,,negative,,,,,,,,,8/17/20,, +8,7/22/20,,Lorton,VA,22079,76,negative,,negative,,,,,,,,,8/17/20,, +8,7/22/20,,Lorton,VA,22079,58,negative,,negative,,,,,,,,,8/17/20,, +8,7/22/20,,Lorton,VA,22079,66,negative,,negative,,,,,,,,,8/17/20,, +8,7/22/20,,Lorton,VA,22079,19,negative,,negative,,,,,,,,,8/17/20,, +8,7/22/20,,Lorton,VA,22079,70,negative,,negative,,,,,,,,,8/17/20,, +8,7/22/20,,Lorton,VA,22079,50,negative,,negative,,,,,,,,,8/17/20,, +7,7/22/20,,Columbia,SC,29229,>85,negative,,negative,,,,,,,,,8/17/20,, +6,7/22/20,,Tampa,FL,33625,20,negative,,negative,,,,,,,,,8/17/20,, +6,7/22/20,,Tampa,FL,33625,68,positive,,positive,,,,,,,,,8/17/20,, +6,7/22/20,,Tampa,FL,33625,>85,negative,,negative,,,,,,,,,8/17/20,, +6,7/22/20,,Tampa,FL,33625,46,positive,,positive,,,,,,,,,8/17/20,, +6,7/22/20,,Tampa,FL,33625,19,negative,,negative,,,,,,,,,8/17/20,, +6,7/22/20,,Tampa,FL,33625,26,negative,,negative,,,,,,,,,8/17/20,, +6,7/22/20,,Tampa,FL,33625,56,negative,,negative,,,,,,,,,8/17/20,, +6,7/22/20,,Tampa,FL,33625,53,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,14,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,38,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,72,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,5,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,17,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,35,positive,,positive,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,85,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,47,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,62,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,74,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,4,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,60,positive,,positive,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,81,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,7,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,>85,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,>85,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,66,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,55,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,82,positive,,positive,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,29,positive,,positive,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,25,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,83,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,5,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,>85,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,>85,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,77,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,58,positive,,positive,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,6,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,36,negative,,negative,,,,,,,,,8/17/20,, +9,7/23/20,,Tampa,FL,33625,24,negative,,negative,,,,,,,,,8/17/20,, \ No newline at end of file diff --git a/quidel_covidtest/tests/test_data_tools.py b/quidel_covidtest/tests/test_data_tools.py index cb611b8f5..7125c8eef 100644 --- a/quidel_covidtest/tests/test_data_tools.py +++ b/quidel_covidtest/tests/test_data_tools.py @@ -76,8 +76,8 @@ def test__slide_window_sum(self, k, expected): @pytest.mark.parametrize("min_obs, expected", [ (1, np.array([0, 0, 0, 0])), - (2, np.array([1/2, 0, 0, 0])), - (8, np.array([1, 1, 5/6, 4/8])), + (2, np.array([1/2, 0, 0, 0])), #(2, np.array([1/2, 0, 0, 0])), + (8, np.array([1/2, 2/4, 3/6, 4/8])), #(8, np.array([1, 1, 5/6, 4/8])), ]) def test__geographical_pooling(self, min_obs, expected): tpooled_tests = np.array([1, 2, 3, 4]) @@ -135,10 +135,19 @@ def test_raw_positive_prop(self, min_obs, expected_pos_prop, expected_se, expect np.array([3, 7, 9, 11]), np.array([5, 10, 15, 20]), np.array([(1 + 0.6 + 0.5)/(2 + 1 + 1), 3.5/7, 5.5/11, 7.5/17]), - np.array([np.sqrt(2.1*(4-2.1)/4/4/3), np.sqrt(3.5*(7-3.5)/7/7/6), - np.sqrt(5.5*(11-5.5)/11/11/10), np.sqrt(7.5*(17-7.5)/17/17/16)]), + np.array([np.sqrt(2.1*(4-2.1)/4/4/3), np.sqrt(3.5*(7-3.5)/7/7/6), + np.sqrt(5.5*(11-5.5)/11/11/10), np.sqrt(7.5*(17-7.5)/17/17/16)]), np.array([3, 6, 10, 16]), ), + (5, # parents case, borrow too much + 2, + np.array([3, 7, 9, 11]), + np.array([5, 10, 15, 20]), + np.array([np.nan, 3.5/7, 5.5/11, 7.5/17]), + np.array([np.nan, np.sqrt(3.5*(7-3.5)/7/7/6), + np.sqrt(5.5*(11-5.5)/11/11/10), np.sqrt(7.5*(17-7.5)/17/17/16)]), + np.array([np.nan, 6, 10, 16]), + ), ]) def test_smoothed_positive_prop(self, min_obs, pool_days, parent_positives, parent_tests, expected_prop, expected_se, expected_sample_sz): From 52a4aa6fc029682346ad850babe0896c5eb5d16a Mon Sep 17 00:00:00 2001 From: Jingjing Tang Date: Tue, 25 Jan 2022 03:08:12 -0500 Subject: [PATCH 23/31] update unit tests in test_run --- quidel_covidtest/tests/test_run.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quidel_covidtest/tests/test_run.py b/quidel_covidtest/tests/test_run.py index 85c5b611e..be6150bc5 100644 --- a/quidel_covidtest/tests/test_run.py +++ b/quidel_covidtest/tests/test_run.py @@ -69,7 +69,7 @@ def test_output_files(self, clean_receiving_dir): assert (df.columns.values == ["geo_id", "val", "se", "sample_size"]).all() df = pd.read_csv(join("./receiving", "20200718_county_covid_ag_smoothed_pct_positive.csv")) - assert set(df.geo_id) == set([51000, 51059, 51143, 51019]) + assert set(df.geo_id) == set([51000, 51059]) # test_intermediate_file flag = None From 9f3f6c3709e727cc1b71acff80a99a8efd09ebd2 Mon Sep 17 00:00:00 2001 From: Jingjing Tang Date: Tue, 25 Jan 2022 03:09:31 -0500 Subject: [PATCH 24/31] delete trailing whitespaces --- quidel_covidtest/delphi_quidel_covidtest/data_tools.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quidel_covidtest/delphi_quidel_covidtest/data_tools.py b/quidel_covidtest/delphi_quidel_covidtest/data_tools.py index 717a2424f..e8958ecfd 100644 --- a/quidel_covidtest/delphi_quidel_covidtest/data_tools.py +++ b/quidel_covidtest/delphi_quidel_covidtest/data_tools.py @@ -71,7 +71,7 @@ def _geographical_pooling(tpooled_tests, tpooled_ptests, min_obs): """ Determine how many samples from the parent geography must be borrowed. - If there are no samples available in the parent, the borrow_prop is 0. + If there are no samples available in the parent, the borrow_prop is 0. If the parent does not have enough samples, we return a borrow_prop of 1. No more samples borrowed from the parent compared to the number of samples we currently have. From 49af72656dfd86857b71db1fddd746b449b9ccb6 Mon Sep 17 00:00:00 2001 From: Dmitry Shemetov Date: Wed, 26 Jan 2022 13:36:17 -0800 Subject: [PATCH 25/31] Add a few tests to double check county censoring --- .../tests/test_data/test_data.csv | 115 ++++++++++++++++-- quidel_covidtest/tests/test_run.py | 8 +- 2 files changed, 114 insertions(+), 9 deletions(-) diff --git a/quidel_covidtest/tests/test_data/test_data.csv b/quidel_covidtest/tests/test_data/test_data.csv index cc4c4ee8b..9f5e907e9 100644 --- a/quidel_covidtest/tests/test_data/test_data.csv +++ b/quidel_covidtest/tests/test_data/test_data.csv @@ -59,6 +59,30 @@ SofiaSerNum,TestDate,Facility,City,State,Zip,PatientAge,Result1,Result2,OverallR 3,7/18/20,,Lorton,VA,22079,51,negative,,negative,,,,,,,,,8/17/20,, 3,7/18/20,,Lorton,VA,22079,5,positive,,positive,,,,,,,,,8/17/20,, 3,7/18/20,,Lorton,VA,22079,22,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24529,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24529,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24529,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24529,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24529,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24529,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24529,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24529,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24529,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24529,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24529,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24529,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24529,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24529,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24529,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24529,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24529,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24529,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24529,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24529,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24529,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24529,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24529,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24529,21,positive,,positive,,,,,,,,,8/17/20,, 1,7/18/20,,TestCity,TestState,24526,3,negative,,negative,,,,,,,,,8/17/20,, 1,7/18/20,,TestCity,TestState,24526,21,positive,,positive,,,,,,,,,8/17/20,, 1,7/18/20,,TestCity,TestState,24526,3,negative,,negative,,,,,,,,,8/17/20,, @@ -81,22 +105,97 @@ SofiaSerNum,TestDate,Facility,City,State,Zip,PatientAge,Result1,Result2,OverallR 1,7/18/20,,TestCity,TestState,24526,21,positive,,positive,,,,,,,,,8/17/20,, 1,7/18/20,,TestCity,TestState,24526,3,negative,,negative,,,,,,,,,8/17/20,, 1,7/18/20,,TestCity,TestState,24526,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24526,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,>85,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,>85,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,>85,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,>85,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,>85,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,>85,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,>85,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,>85,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,>85,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,>85,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,>85,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,>85,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,>85,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,>85,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,>85,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,>85,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,>85,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,>85,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,>85,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,>85,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,>85,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,>85,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,>85,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,>85,positive,,positive,,,,,,,,,8/17/20,, 1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,TestCity,TestState,24527,150,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,>85,positive,,positive,,,,,,,,,8/17/20,, 1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,TestCity,TestState,24527,150,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,>85,positive,,positive,,,,,,,,,8/17/20,, 1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,TestCity,TestState,24527,150,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,>85,positive,,positive,,,,,,,,,8/17/20,, 1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,TestCity,TestState,24527,150,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,>85,positive,,positive,,,,,,,,,8/17/20,, 1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,TestCity,TestState,24527,150,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,>85,positive,,positive,,,,,,,,,8/17/20,, 1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,TestCity,TestState,24527,150,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,>85,positive,,positive,,,,,,,,,8/17/20,, 1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,TestCity,TestState,24527,150,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,>85,positive,,positive,,,,,,,,,8/17/20,, 1,7/18/20,,TestCity,TestState,24527,3,negative,,negative,,,,,,,,,8/17/20,, -1,7/18/20,,TestCity,TestState,24527,150,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24527,>85,positive,,positive,,,,,,,,,8/17/20,, 3,7/19/20,,Baltimore,MD,21229,>85,negative,,negative,,,,,,,,,8/17/20,, 3,7/19/20,,Baltimore,MD,21229,39,negative,,negative,,,,,,,,,8/17/20,, 3,7/19/20,,Baltimore,MD,21229,51,negative,,negative,,,,,,,,,8/17/20,, diff --git a/quidel_covidtest/tests/test_run.py b/quidel_covidtest/tests/test_run.py index be6150bc5..24dedae65 100644 --- a/quidel_covidtest/tests/test_run.py +++ b/quidel_covidtest/tests/test_run.py @@ -68,8 +68,14 @@ def test_output_files(self, clean_receiving_dir): ) assert (df.columns.values == ["geo_id", "val", "se", "sample_size"]).all() + df = pd.read_csv(join("./receiving", "20200718_county_covid_ag_raw_pct_positive.csv")) + # TODO: should megacounty 51000 be here (it currently is)? + assert set(df.geo_id) == set([51143, 51059, 51000]) + df = pd.read_csv(join("./receiving", "20200718_county_covid_ag_smoothed_pct_positive.csv")) - assert set(df.geo_id) == set([51000, 51059]) + # TODO: should megacounty 51000 be here (it currently isn't)? + assert set(df.geo_id) == set([51019, 51143, 51059]) + assert 1 == 2 # test_intermediate_file flag = None From 3218b1e8f87b38e48fbe853ef3654c9facfb317d Mon Sep 17 00:00:00 2001 From: Dmitry Shemetov Date: Wed, 26 Jan 2022 13:56:46 -0800 Subject: [PATCH 26/31] Remove faux-breakpoint, update test_data, update test_run --- quidel_covidtest/tests/test_data/test_data.csv | 4 ++++ quidel_covidtest/tests/test_run.py | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/quidel_covidtest/tests/test_data/test_data.csv b/quidel_covidtest/tests/test_data/test_data.csv index 9f5e907e9..e93a109d4 100644 --- a/quidel_covidtest/tests/test_data/test_data.csv +++ b/quidel_covidtest/tests/test_data/test_data.csv @@ -59,6 +59,10 @@ SofiaSerNum,TestDate,Facility,City,State,Zip,PatientAge,Result1,Result2,OverallR 3,7/18/20,,Lorton,VA,22079,51,negative,,negative,,,,,,,,,8/17/20,, 3,7/18/20,,Lorton,VA,22079,5,positive,,positive,,,,,,,,,8/17/20,, 3,7/18/20,,Lorton,VA,22079,22,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24534,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24534,21,positive,,positive,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24534,3,negative,,negative,,,,,,,,,8/17/20,, +1,7/18/20,,TestCity,TestState,24534,21,positive,,positive,,,,,,,,,8/17/20,, 1,7/18/20,,TestCity,TestState,24529,3,negative,,negative,,,,,,,,,8/17/20,, 1,7/18/20,,TestCity,TestState,24529,21,positive,,positive,,,,,,,,,8/17/20,, 1,7/18/20,,TestCity,TestState,24529,3,negative,,negative,,,,,,,,,8/17/20,, diff --git a/quidel_covidtest/tests/test_run.py b/quidel_covidtest/tests/test_run.py index 24dedae65..f5b9d9729 100644 --- a/quidel_covidtest/tests/test_run.py +++ b/quidel_covidtest/tests/test_run.py @@ -74,8 +74,7 @@ def test_output_files(self, clean_receiving_dir): df = pd.read_csv(join("./receiving", "20200718_county_covid_ag_smoothed_pct_positive.csv")) # TODO: should megacounty 51000 be here (it currently isn't)? - assert set(df.geo_id) == set([51019, 51143, 51059]) - assert 1 == 2 + assert set(df.geo_id) == set([51000, 51019, 51143, 51059]) # test_intermediate_file flag = None From 5c6d79886ff90cde5e52448eb6d9bf3ce6bbcc45 Mon Sep 17 00:00:00 2001 From: Jingjing Tang Date: Thu, 27 Jan 2022 14:26:46 -0500 Subject: [PATCH 27/31] fix the test in test_run --- quidel_covidtest/tests/test_run.py | 1 - 1 file changed, 1 deletion(-) diff --git a/quidel_covidtest/tests/test_run.py b/quidel_covidtest/tests/test_run.py index f5b9d9729..3fcfa2c1f 100644 --- a/quidel_covidtest/tests/test_run.py +++ b/quidel_covidtest/tests/test_run.py @@ -73,7 +73,6 @@ def test_output_files(self, clean_receiving_dir): assert set(df.geo_id) == set([51143, 51059, 51000]) df = pd.read_csv(join("./receiving", "20200718_county_covid_ag_smoothed_pct_positive.csv")) - # TODO: should megacounty 51000 be here (it currently isn't)? assert set(df.geo_id) == set([51000, 51019, 51143, 51059]) # test_intermediate_file From 3e9232e0605f23bc1033b4e13faad38d56b710e7 Mon Sep 17 00:00:00 2001 From: Jingjing Tang Date: Thu, 27 Jan 2022 14:28:34 -0500 Subject: [PATCH 28/31] remove the question in comments --- quidel_covidtest/tests/test_run.py | 1 - 1 file changed, 1 deletion(-) diff --git a/quidel_covidtest/tests/test_run.py b/quidel_covidtest/tests/test_run.py index 3fcfa2c1f..9d65ebb68 100644 --- a/quidel_covidtest/tests/test_run.py +++ b/quidel_covidtest/tests/test_run.py @@ -69,7 +69,6 @@ def test_output_files(self, clean_receiving_dir): assert (df.columns.values == ["geo_id", "val", "se", "sample_size"]).all() df = pd.read_csv(join("./receiving", "20200718_county_covid_ag_raw_pct_positive.csv")) - # TODO: should megacounty 51000 be here (it currently is)? assert set(df.geo_id) == set([51143, 51059, 51000]) df = pd.read_csv(join("./receiving", "20200718_county_covid_ag_smoothed_pct_positive.csv")) From ab25b356a097c542291ef00a14eefe4f91e6ac99 Mon Sep 17 00:00:00 2001 From: Jingjing Tang Date: Thu, 27 Jan 2022 15:05:31 -0500 Subject: [PATCH 29/31] add tests for values --- quidel_covidtest/tests/test_run.py | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/quidel_covidtest/tests/test_run.py b/quidel_covidtest/tests/test_run.py index 9d65ebb68..d9e28108a 100644 --- a/quidel_covidtest/tests/test_run.py +++ b/quidel_covidtest/tests/test_run.py @@ -3,8 +3,9 @@ from os.path import join import pandas as pd +import numpy as np -from delphi_utils import read_params, add_prefix +from delphi_utils import add_prefix from delphi_quidel_covidtest.constants import PARENT_GEO_RESOLUTIONS, NONPARENT_GEO_RESOLUTIONS, \ SENSORS from delphi_quidel_covidtest.run import run_module @@ -69,10 +70,32 @@ def test_output_files(self, clean_receiving_dir): assert (df.columns.values == ["geo_id", "val", "se", "sample_size"]).all() df = pd.read_csv(join("./receiving", "20200718_county_covid_ag_raw_pct_positive.csv")) + #ZIP 24534, FIPS 51083 has 4 counts, 2 positives + #ZIP 24529, FIPS 51117 has 24 counts, 12 positives + #ZIP 24526, FIPS 51019 has 49 counts, 26 positives + #MEGAFIPS 51000, should have 4+24+49 = 77 counts, 2+12+26 = 40 positives + #ZIP 24527, FIPS 51143 has 64 counts, 32 positives + #ZIP 22079, FIPS 51059 has 60 counts, 24 positives assert set(df.geo_id) == set([51143, 51059, 51000]) + assert set(df.sample_size) == set([64, 60, 77]) + assert np.allclose(df.val.values, [(40+0.5)/(77+1)*100, (24+0.5)/(60+1)*100, + (32+0.5)/(64+1)*100], equal_nan=True) + df = pd.read_csv(join("./receiving", "20200718_county_covid_ag_smoothed_pct_positive.csv")) assert set(df.geo_id) == set([51000, 51019, 51143, 51059]) + assert set(df.sample_size) == set([50, 50, 64, 60]) + parent_test = 4+24+49+64+60 + parent_pos = 2+12+26+32+24 + #ZIP 24526, FIPS 51019 has 49 counts, 26 positives, borrow 1 pseudo counts from VA + #MEGAFIPS 51000, should have 4+24 = 28 counts, 2+12 = 14 positives, borrow 22 pseudo counts + #ZIP 24527, FIPS 51143 has 64 counts, 32 positives, do not borrow + #ZIP 22079, FIPS 51059 has 60 counts, 24 positives, do not borrow + assert np.allclose(df.val.values, + [(14+parent_pos*22/parent_test+0.5)/(50+1)*100, + (26+parent_pos*1/parent_test+0.5)/(50+1)*100, + (24+0.5)/(60+1)*100, + (32+0.5)/(64+1)*100], equal_nan=True) # test_intermediate_file flag = None From 8fbff9320752eff0795d595db22b76a0cc2b0162 Mon Sep 17 00:00:00 2001 From: Jingjing Tang Date: Wed, 2 Feb 2022 16:49:51 -0500 Subject: [PATCH 30/31] add archiver section to quidel params --- quidel_covidtest/params.json.template | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/quidel_covidtest/params.json.template b/quidel_covidtest/params.json.template index a2996b032..797249fcd 100644 --- a/quidel_covidtest/params.json.template +++ b/quidel_covidtest/params.json.template @@ -20,6 +20,15 @@ "wip_signal": [""], "test_mode": false }, + "archive": { + "aws_credentials": { + "aws_access_key_id": "{{ delphi_aws_access_key_id }}", + "aws_secret_access_key": "{{ delphi_aws_secret_access_key }}" + }, + "bucket_name": "delphi-covidcast-indicator-output", + "cache_dir": "./archivediffer_cache", + "indicator_prefix": "quidel" + } "validation": { "common": { "data_source": "quidel", From 963bb5a773de5ce7f70bc89b6f784a81f3903ab6 Mon Sep 17 00:00:00 2001 From: Jingjing Tang Date: Wed, 2 Feb 2022 16:51:37 -0500 Subject: [PATCH 31/31] fix params --- quidel_covidtest/params.json.template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quidel_covidtest/params.json.template b/quidel_covidtest/params.json.template index 797249fcd..e96d2ccbc 100644 --- a/quidel_covidtest/params.json.template +++ b/quidel_covidtest/params.json.template @@ -28,7 +28,7 @@ "bucket_name": "delphi-covidcast-indicator-output", "cache_dir": "./archivediffer_cache", "indicator_prefix": "quidel" - } + }, "validation": { "common": { "data_source": "quidel",