def test_run_inference(self): local_df = pd.DataFrame({ 'Time': [1, 2, 3, 5, 6], 'Incidence Number': [10, 3, 4, 6, 9] }) imp_df = pd.DataFrame({ 'Time': [1, 2, 3, 5, 6], 'Incidence Number': [10, 3, 4, 6, 9] }) ser_int1 = [[1, 2, 1, 0, 0, 0]] ser_int2 = [[1, 2], [3, 4]] inference1 = bp.LocImpBranchProPosteriorMultSI(local_df, imp_df, 0.3, ser_int1, 1, 0.2) inference1.run_inference(tau=2) inference2 = bp.LocImpBranchProPosteriorMultSI(local_df, imp_df, 0.3, ser_int2, 1, 0.2) inference2.run_inference(tau=2) self.assertEqual(len(inference1.inference_estimates), 3) self.assertEqual(len(inference1.inference_times), 3) self.assertEqual(len(inference1.inference_posterior.mean()), 3) self.assertEqual(len(inference2.inference_estimates), 3) self.assertEqual(len(inference2.inference_times), 3) self.assertEqual(len(inference2.inference_posterior.mean()), 3) def progress_fn(i): pass inference3 = bp.LocImpBranchProPosteriorMultSI(local_df, imp_df, 0.3, ser_int2, 1, 0.2) inference3.run_inference(tau=2, progress_fn=progress_fn)
def test__init__(self): local_df = pd.DataFrame({ 'Time': [1, 2, 3, 5, 6], 'Incidence Number': [10, 3, 4, 6, 9] }) imp_df = pd.DataFrame({ 'Time': [1, 2, 3, 5, 6], 'Incidence Number': [10, 3, 4, 6, 9] }) ser_ints = [[1, 2], [0, 1]] epsilon = 0.3 bp.LocImpBranchProPosteriorMultSI(local_df, imp_df, epsilon, ser_ints, 1, 0.2) with self.assertRaises(TypeError) as test_excep: bp.LocImpBranchProPosteriorMultSI(local_df, imp_df, epsilon, [[0], 0], 1, 0.2) self.assertTrue('must be iterable' in str(test_excep.exception)) with self.assertRaises(TypeError) as test_excep: bp.LocImpBranchProPosteriorMultSI(local_df, imp_df, epsilon, [[1], ['zero']], 1, 0.2) self.assertTrue( 'distribution must contain' in str(test_excep.exception))
def setUpClass(cls): """Set up the class using real data and inference. The purpose is to test the figure function under realistic conditions. """ # Make a fake set of serial intervals serial_intervals = np.array([[0.1, 0.5, 0.2, 0.2], [0.2, 0.4, 0.2, 0.2], [0.1, 0.5, 0.4, 0.0]]) # Read Ontario data data = pd.read_csv( '../branchpro/branchpro/data_library/covid_ontario/ON.csv')[:51] locally_infected_cases = data['Incidence Number'] imported_cases = data['Imported Cases'] # Get time points num_timepoints = max(data['Time']) start_times = np.arange(1, num_timepoints+1, dtype=int) times = np.arange(num_timepoints+1) # Inference R_t profile, but using the LocImpBranchProPosterior tau = 2 R_t_start = tau+1 a = 1 b = 0.8 # Transform our incidence data into pandas dataframes inc_data = pd.DataFrame( { 'Time': start_times, 'Incidence Number': locally_infected_cases } ) imported_inc_data = pd.DataFrame( { 'Time': start_times, 'Incidence Number': imported_cases } ) # Run inference with epsilon = 1 to get R trajectory inference = branchpro.LocImpBranchProPosteriorMultSI( inc_data=inc_data, imported_inc_data=imported_inc_data, epsilon=1, daily_serial_intervals=serial_intervals, alpha=a, beta=1/b) inference.run_inference(tau=tau) intervals = inference.get_intervals(central_prob=.95) new_rs = intervals['Mean'].values.tolist() # Run simulation of local cases for various values of epsilon epsilon_values = [0.25, 1.0, 1.5] initial_r = new_rs[0] si = np.median(serial_intervals, axis=0) parameters = 0 # initial number of cases all_local_cases = [] num_simulations = 100 samples = [] central_prob = 0.95 for _, epsilon in enumerate(epsilon_values): m = branchpro.LocImpBranchProModel(initial_r, si, epsilon) m.set_r_profile(new_rs, start_times[R_t_start:]) m.set_imported_cases(start_times, imported_cases) for sim in range(num_simulations): samples.append(m.simulate(parameters, times)) simulation_estimates = np.mean(np.vstack(samples), axis=0) lb = 100*(1-central_prob)/2 ub = 100*(1+central_prob)/2 simulation_interval = np.percentile( np.vstack(samples), q=np.array([lb, ub]), axis=0) simulation_df = pd.DataFrame( { 'Mean': simulation_estimates, 'Lower bound CI': simulation_interval[0], 'Upper bound CI': simulation_interval[1] } ) all_local_cases.append(simulation_df) cls.imported_cases = imported_cases cls.start_times = start_times cls.R_t_start = R_t_start cls.new_rs = new_rs cls.epsilon_values = epsilon_values cls.all_local_cases = all_local_cases
def setUpClass(cls): """Set up the class using real data and inference. The purpose is to test the figure function under realistic conditions. """ # Make a fake set of serial intervals serial_intervals = np.array([[0.1, 0.5, 0.2, 0.2], [0.2, 0.4, 0.2, 0.2], [0.1, 0.5, 0.4, 0.0]]) # Read Ontario data data = pd.read_csv( '../branchpro/branchpro/data_library/covid_ontario/ON.csv')[:51] locally_infected_cases = data['Incidence Number'] imported_cases = data['Imported Cases'] # Get time points from the data num_timepoints = max(data['Time']) start_times = np.arange(1, num_timepoints+1, dtype=int) # Same inference, but using the LocImpBranchProPosterior tau = 6 a = 1 b = 0.2 # Run inferences for different values of epsilon column_names = ['Time Points', 'Mean', 'Lower bound CI', 'Upper bound CI', 'Central Probability', 'Epsilon'] epsilon_range = [0.1 + 0.1 * i for i in range(30)] all_intervals = pd.DataFrame(columns=column_names) # Transform our incidence data into pandas dataframes inc_data = pd.DataFrame( { 'Time': start_times, 'Incidence Number': locally_infected_cases } ) imported_inc_data = pd.DataFrame( { 'Time': start_times, 'Incidence Number': imported_cases } ) for epsilon in epsilon_range: inference = branchpro.LocImpBranchProPosteriorMultSI( inc_data=inc_data, imported_inc_data=imported_inc_data, epsilon=epsilon, daily_serial_intervals=serial_intervals, alpha=a, beta=b) inference.run_inference(tau=tau) intervals = inference.get_intervals(central_prob=.95) intervals['Epsilon'] = [epsilon] * len(intervals.index) all_intervals = all_intervals.append(intervals) cls.epsilon_range = epsilon_range cls.all_intervals = all_intervals
def update_posterior(self, mean, stdev, tau, central_prob, epsilon=None, progress_fn=None): """Update the posterior distribution based on slider values. Parameters ---------- mean (float) updated position on the slider for the mean of the prior for the Branch Pro model in the posterior. stdev (float) updated position on the slider for the standard deviation of the prior for the Branch Pro model in the posterior. tau (int) updated position on the slider for the tau window used in the running of the inference of the reproduction numbers of the Branch Pro model in the posterior. central_prob (float) updated position on the slider for the level of the computed credible interval of the estimated R number values. epsilon (float) updated position on the slider for the constant of proportionality between local and imported cases for the Branch Pro model in the posterior. progress_fn Function of integer argument to send to posterior run_inference. It can be used for dash callbacks set_progress (see update_posterior_storage in the app script) Returns ------- pandas.DataFrame The posterior distribution, summarized in a dataframe with the following columns: 'Time Points', 'Mean', 'Lower bound CI' and 'Upper bound CI' """ new_alpha = (mean / stdev)**2 new_beta = mean / (stdev**2) data = self.session_data.get('data_storage') if data is None: raise dash.exceptions.PreventUpdate() time_label, inc_label = data.columns[:2] num_cols = len(self.session_data.get('interval_storage').columns) prior_params = (new_alpha, new_beta) labels = {'time_key': time_label, 'inc_key': inc_label} if num_cols == 1: serial_interval = self.session_data.get( 'interval_storage').iloc[:, 0].values if 'Imported Cases' in data.columns: # Separate data into local and imported cases imported_data = pd.DataFrame({ time_label: data[time_label], inc_label: data['Imported Cases'] }) # Posterior follows the LocImp behaviour posterior = bp.LocImpBranchProPosterior( data, imported_data, epsilon, serial_interval, *prior_params, **labels) else: # Posterior follows the simple behaviour posterior = bp.BranchProPosterior(data, serial_interval, *prior_params, **labels) posterior.run_inference(tau) else: serial_intervals = self.session_data.get( 'interval_storage').values.T if 'Imported Cases' in data.columns: # Separate data into local and imported cases imported_data = pd.DataFrame({ time_label: data[time_label], inc_label: data['Imported Cases'] }) # Posterior follows the LocImp behaviour posterior = bp.LocImpBranchProPosteriorMultSI( data, imported_data, epsilon, serial_intervals, *prior_params, **labels) else: # Posterior follows the simple behaviour posterior = bp.BranchProPosteriorMultSI( data, serial_intervals, *prior_params, **labels) posterior.run_inference(tau, progress_fn=progress_fn) return posterior.get_intervals(central_prob)