def __init__(self, csv_file_name, wtp_range, csv_file_name_proj_thresholds='ProjectedOptimalThreshold.csv'): self.cols = io.read_csv_cols( file_name=csv_file_name, n_cols=3, if_ignore_first_row=True, if_convert_float=True) self.wtps = self.cols[0] self.OnTs = self.cols[1] self.OffTs = self.cols[2] self.RegToOn = Reg.ExpRegression(x=self.wtps, y=self.OnTs, if_c0_zero=True) print(self.RegToOn.get_coeffs()) self.RegToOff = Reg.ExpRegression(x=self.wtps, y=self.OffTs, if_c0_zero=True) print(self.RegToOff.get_coeffs()) wtps = np.linspace(wtp_range[0], wtp_range[1], 13) to_on_ts = self.RegToOn.get_predicted_y(wtps) to_off_ts = self.RegToOff.get_predicted_y(wtps) rows = [] for i in range(len(wtps)): row = [wtps[i], to_on_ts[i], to_off_ts[i]] rows.append(row) io.write_csv(rows=rows, file_name=csv_file_name_proj_thresholds)
def sample_posterior(self, n_samples): """ sample the posterior distribution of the mortality probability, :param n_samples: number of samples from the posterior distribution """ # specifying the seed of the numpy random number generator np.random.seed(1) # cohort ids self.cohortIDs = range(n_samples) # find values of mortality probability at which the posterior should be evaluated self.mortalitySamples = np.random.uniform(low=Sets.PRIOR_L, high=Sets.PRIOR_U, size=Sets.PRIOR_N) # create a multi cohort multi_cohort = SurvivalCls.MultiCohort( ids=self.cohortIDs, mortality_probs=self.mortalitySamples, pop_sizes=[Sets.SIM_POP_SIZE] * Sets.PRIOR_N) # simulate the multi cohort multi_cohort.simulate(n_time_steps=Sets.TIME_STEPS) # calculate the likelihood of each simulated cohort weights = [] for cohort_id in self.cohortIDs: # get the average survival time for this cohort mean = multi_cohort.multiCohortOutcomes.meanSurvivalTimes[ cohort_id] # construct a normal likelihood # with mean calculated from the simulated data and standard deviation from the clinical study. # evaluate this pdf (probability density function) at the mean reported in the clinical study. weight = stat.norm.pdf(x=Sets.OBS_MEAN, loc=mean, scale=Sets.OBS_STDEV) # store the weight weights.append(weight) # normalize the likelihood weights sum_weights = sum(weights) self.normalizedWeights = np.divide(weights, sum_weights) # produce the list to report the results csv_rows = \ [['Cohort ID', 'Likelihood Weights', 'Mortality Prob']] # list containing the calibration results for i in range(len(self.mortalitySamples)): csv_rows.append([ self.cohortIDs[i], self.normalizedWeights[i], self.mortalitySamples[i] ]) # write the calibration result into a csv file IO.write_csv(file_name='CalibrationResults.csv', rows=csv_rows)
def export_to_csv(self, file_name='PartialRank.csv', decimal=3): formatedResults = [['Parameter', 'Coefficient', 'P-Value']] for row in self.results: name = row[0] coef = F.format_number(number=row[1], deci=decimal) p = F.format_number(number=row[2], deci=decimal) formatedResults.append([name, coef, p]) IO.write_csv(file_name=file_name, rows=formatedResults)
def export_means_and_intervals(self, poster_file='ParameterEstimates.csv', significance_level=0.05, sig_digits=3, param_names=None, prior_info_csv_file=None): """ calculate the mean and credible intervals of parameters specified by ids :param poster_file: csv file where the posterior ranges should be stored :param significance_level: :param sig_digits: number of significant digits :param param_names: (list) of parameter names :param prior_info_csv_file: (string) filename where parameter prior ranges are located :return: """ results = self.get_means_and_intervals(significance_level=significance_level, sig_digits=sig_digits, param_names=param_names, prior_info_csv_file=prior_info_csv_file) # write parameter estimates and credible intervals IO.write_csv(rows=results, file_name=poster_file)
def export_to_csv(self, corrs='r', file_name='Correlations.csv', decimal=3, delimiter=','): """ formats the correlation coefficients and p-value to the specified decimal point and exports to a csv file :param corrs: (string) or (list of strings) from 'r' for Pearson's, 'rho' for Spearman's rank correlation, 'p' for partial correlation, and 'pr' for partial rank correlation :param file_name: file name :param decimal: decimal points to round the estimates to :param delimiter: to separate by comma, use ',' and by tab, use '\t' """ if not isinstance(corrs, list): corrs = [corrs] # make the header tile_row = ['Parameter'] for corr in corrs: tile_row.append(self._full_name(corr=corr)) tile_row.append('P-value') # add the header formatted_results = [tile_row] # add the names of parameters (first column) for name in self.dicParameterValues: formatted_results.append([name]) # calculate all forms of correlation requested for corr in corrs: results, text = self._get_results_text(corr=corr) i = 1 for par, values in results.items(): coef = F.format_number(number=values[0], deci=decimal) p = F.format_number(number=values[1], deci=decimal) formatted_results[i].extend([coef, p]) i += 1 IO.write_csv(file_name=file_name, rows=formatted_results, delimiter=delimiter)
def export_results(self, directory): rows = [[self.seed, self.sum]] name = 'Seed ' + str(self.seed) + ".csv" IO.write_csv(rows=rows, file_name=name, directory=directory)
from SimPy import InOutFunctions as OutSupport myList = [['Col1', 'Col2', 'Col3', 'Col4']] #myList.append(['s1', 's2', 's3']) #myList.append(['A', '-100', '1,000']) for i in range(1, 10): myList.append(['row'+str(i), i, 2*i, 3*i]) OutSupport.write_csv(file_name ='myCSV.csv', rows=myList, directory='CSVFolder')
def resample_param_values(self, csvfile_param_values_and_weights, n, weight_col, csvfile_resampled_params, sample_by_weight=True, columns_to_be_deleted=(), seed=0): """ :param csvfile_param_values_and_weights: (string) csv file where the values of parameters along with their weights are provided. It assumes that 1) the first row contains the name of all parameters 2) rows contains the weight and the parameter values 3) rows are in decreasing order of parameter weights :param n: (int) number of parameter values to resamples :param weight_col: (int) index of the columns where the weights of parameter values are located. :param csvfile_resampled_params: (string) csvfile where the resampled parameter values will be stored. The first row will be the names of parameters. :param sample_by_weight: (bool) set to true to sample parameters by weight. If set to False, the first n parameters will be selected. :param columns_to_be_deleted: (list of string) list of column names to be deleted from analysis :param seed: (int) seed of the random number generator to resample parameters """ # read parameter weights and values rows_of_weights_and_parameter_values = IO.read_csv_rows( file_name=csvfile_param_values_and_weights, if_ignore_first_row=False, if_convert_float=True) # store header rows_of_selected_param_values = [rows_of_weights_and_parameter_values[0]] if not sample_by_weight: # choose the first n parameter values for i, row in enumerate(rows_of_weights_and_parameter_values): if i > n: # first rwo is the header break elif i > 0 and row[weight_col] > 0: rows_of_selected_param_values.append(row) else: # weight weights = [] for row in rows_of_weights_and_parameter_values: weights.append(row[weight_col]) del(weights[0]) # header # sample rows rng = np.random.RandomState(seed=seed) sampled_indices = rng.choice(a=range(len(weights)), size=n, p=weights) # build sampled rows for i in sampled_indices: rows_of_selected_param_values.append(rows_of_weights_and_parameter_values[i+1]) IO.write_csv(rows=rows_of_selected_param_values, file_name=csvfile_resampled_params) self.dictOfParamValues = IO.read_csv_cols_to_dictionary(file_name=csvfile_resampled_params, if_convert_float=True) # check if parameters have values for key, values in self.dictOfParamValues.items(): if len(values) == 0: raise ValueError('Parameter values are not provided in '+csvfile_resampled_params+'.') for name in columns_to_be_deleted: del (self.dictOfParamValues[name])
def sample_posterior(self, n_samples): """ sample the posterior distribution of the mortality probability, :param n_samples: number of samples from the posterior distribution """ # specifying the seed of the numpy random number generator np.random.seed(1) # cohort ids => list self.cohortIDs = range(n_samples) # find values of mortality probability at which the posterior should be evaluated => list of mortality samples self.mortalitySamples = np.random.uniform(low=CalibSets.POST_L, high=CalibSets.POST_U, size=CalibSets.POST_N) # create a multi cohort # multi_cohort_SOC = Cls.MultiCohort(ids=self.cohortIDs, # pop_size=[CalibSets.SIM_POP_SIZE]*CalibSets.POST_N, # parameters=P.ParametersFixed(diagnostic=P.Diagnostic.SOC, # calibrate_mortality=self.mortalitySamples)) multi_cohort_SOC = Cls.MultiCohort( ids=self.cohortIDs, mortality_probs=self.mortalitySamples, pop_sizes=[CalibSets.SIM_POP_SIZE] * CalibSets.POST_N # passing in lists ) # simulate the multi cohort multi_cohort_SOC.simulate(sim_length=CalibSets.SIM_LENGTH) # calculate the likelihood of each simulated cohort weights = [] for cohort_id in self.cohortIDs: # get the 1-year survival probability for this cohort proportion = multi_cohort_SOC.multiCohortOutcomes.mortality1Year[ cohort_id] # construct a binomial likelihood # with p calculated from the simulated data # evaluate this pdf (probability density function) at the (k, n) reported in the clinical study. weight = stat.binom.pmf(k=CalibSets.OBS_DEAD, n=CalibSets.OBS_N, p=proportion, loc=0) # store the weight weights.append(weight) # print(cohort_id, proportion, weight) # normalize the likelihood weights sum_weights = np.sum(weights) self.normalizedWeights = np.divide(weights, sum_weights) # produce the list to report the results csv_rows = \ [['Cohort ID', 'Likelihood Weights', 'Mortality Prob']] # list containing the calibration results for i in range(len(self.mortalitySamples)): csv_rows.append([ self.cohortIDs[i], self.normalizedWeights[i], self.mortalitySamples[i] ]) # write the calibration result into a csv file InOutSupport.write_csv(file_name='CalibrationResults.csv', rows=csv_rows) # re-sample mortality probability (with replacement) according to likelihood weights self.mortalityResamples = np.random.choice(a=self.mortalitySamples, size=n_samples, replace=True, p=self.normalizedWeights)
import SimPy.InOutFunctions as IO from covid19 import Support as Support R_On = [1, 3] R_Off = [0.2, 1] N = 10 IO.write_csv(rows=Support.generate_square_policies(R_On, R_Off, N), file_name='../csv_files/ThresholdsRt.csv')
from SimPy import InOutFunctions as OutSupport myList = [['Col1', 'Col2', 'Col3']] for i in range(1, 10): myList.append([i, 2*i, 3*i]) OutSupport.write_csv('myCSV', myList)
import SimPy.InOutFunctions as IO from covid19 import Support as Support R_On = [1, 3] R_Off = [0.3, 1] I = [100, 500] N = 3 RPolicies = Support.generate_square_policies(R_On, R_Off, N) IPolicies = Support.generate_square_policies(I, I, N) RIPolicies = [] for R in RPolicies: for I in IPolicies: RI = R.copy() RI.extend(I) RIPolicies.append(RI) IO.write_csv(rows=RIPolicies, file_name='../csv_files/ThresholdsRtI.csv')
import SimPy.InOutFunctions as IO from covid19 import Support as Support ICU_CAPACITY = 0.89 / 10000 * 2 MAX_I = 0.1 # MAX = 30 * ICU_CAPACITY # MIN = 0 MAX = MAX_I / 5 MIN = 0.0005 N = 20 IO.write_csv(rows=Support.generate_triangular_scenarios(MIN, MAX, N), file_name='../csv_files/ICUPolicies.csv')
import SimPy.InOutFunctions as IO from covid19 import Support as Support Incidence = [1500, 14000] DeltaIncidence = [50, 3000] N = 10 IO.write_csv(rows=Support.generate_square_policies(Incidence, DeltaIncidence, N), file_name='../csv_files/IncidencePolicies.csv')
import SimPy.InOutFunctions as IO from covid19 import Support as Support I_on = [300, 400] # 150, 75 I_off = [75, 125] N = 3 IO.write_csv(rows=Support.generate_square_policies(I_on, I_off, N), file_name='../csv_files/ThresholdsI.csv') # I = [10/10000, 60/10000] # IO.write_csv(rows=Support.generate_triangular_scenarios(I[0], I[1], N), # file_name='../csv_files/ThresholdsI.csv')
def write_to_csv(self, file_name, directory): io.write_csv(rows=self.wtpAndThresholds, file_name=file_name, directory=directory)
def write_to_csv(self, file_name, directory): io.write_csv(rows=self.wtpToffTon, file_name=file_name, directory=directory)
def calculate_means_and_intervals(self, poster_file='ParameterEstimates.csv', significance_level=0.05, deci=3, ids=None, csv_file_name_prior=None): """ calculate the mean and credible intervals of parameters specified by ids :param poster_file: csv file where the posterior ranges should be stored :param significance_level: :param deci: :param ids: :param csv_file_name_prior: (string) filename where parameter prior ranges are located :return: """ # read prior distributions priors = None if csv_file_name_prior is not None: priors = IO.read_csv_rows(file_name=csv_file_name_prior, if_ignore_first_row=True, delimiter=',', if_convert_float=True) results = [] # list of parameter estimates and credible intervals par_id = 0 for key, value in self.dictOfParams.items(): # skip these columns if key in ['Simulation Replication', 'Random Seed']: continue # if estimates and credible intervals should be calculated for this parameter if_record = False if ids is None: if_record = True elif par_id in ids: if_record = True # record the calculated estimate and credible interval if if_record: if priors is None: decimal = deci form = '' multip = 1 else: decimal = priors[par_id][Column.DECI.value] decimal = 0 if decimal is None else decimal form = priors[par_id][Column.FORMAT.value] multip = priors[par_id][Column.MULTIPLIER.value] if multip is None: data = value else: multip = float(multip) data = [multip * x for x in value] sum_stat = Stat.SummaryStat(name=key, data=data) mean_text = Format.format_number(number=sum_stat.get_mean(), deci=decimal, format=form) PI_text = Format.format_interval( interval=sum_stat.get_PI(significance_level), deci=decimal, format=form) results.append([par_id, key, mean_text, PI_text]) # next parameter par_id += 1 # write parameter estimates and credible intervals IO.write_csv(rows=results, file_name=poster_file)