def test_get_default_params(self): params = get_default_params() self.assertIsNot(params, None) params_key_set = set(params.keys()) self.assertIn('parameters', params_key_set) self.assertIn('rules', params_key_set) series = run_sir_h(params['parameters'], params['rules']) self.assertIsNot(series, None)
def test_model_execution(self): params = get_default_params() series1 = run_sir_h(params['parameters'], params['rules']) tmp_file = NamedTemporaryFile() export_json(tmp_file.name, params['parameters'], params['rules'], params['other']) read_params = import_json(tmp_file.name) tmp_file.close() series2 = run_sir_h(read_params[0], read_params[1]) self.assertEqual(series1, series2)
def test_import_export_json(self): params = get_default_params() tmp_file = NamedTemporaryFile(delete=False) export_json(tmp_file.name, params['parameters'], params['rules'], params['other']) read_params = import_json(tmp_file.name) tmp_file.close() remove(tmp_file.name) self.assertEqual(read_params[0], params['parameters']) # self.assertEqual(read_params[1], params['rules']) self.assertEqual(set([str(x) for x in read_params[1]]), set([str(x) for x in params['rules']])) self.assertEqual(read_params[2], params['other'])
def fit_data(series: list, measures: str, variables: str, model: str, optim:str, outputdir:str, suffix:str, n:int) -> None: # python3 -m flowsim.labs.model_fit.optimise -d ${series} -i "${measures}" -v "${variables}" -m ${model} --opt ${algo} --noplot --path "${out_path}" -s datanum_$i -n $i ; default_model_params = get_default_params() day0 = default_model_params['data']['day0'] model_parameters = default_model_params['parameters'] model_rules = default_model_params['rules'] target = pd.read_csv(measures, sep=';').to_numpy() target = target[:n, ] if model == 'disc_int': model_parameters['integer_flux'] = True if not os.path.exists(outputdir): mkdir(outputdir) # timestamp = datetime.datetime.now().strftime("%y%m%d_%H%M%S_") timestamp = '' basename = f'{outputdir}/{timestamp}{suffix}' ''' defining simulator model functions ''' if model == 'diff': def simulator_model_func(p, s, **kwargs): return model_diff(p, s, **kwargs) elif model == 'disc' or model == 'disc_int': def simulator_model_func(p, s, **kwargs): return model_disc({'parameters': p, 'rules': model_rules}, s, **kwargs) else: simulator_model_func = None simple_data_tokens = [p.split('_')[-1] for p in series] full_data_tokens = series with open(variables) as json_file: opt_variables = json.load(json_file) params_init_min_max = dict() for k, v in opt_variables.items(): params_init_min_max[k] = tuple(v) x_data = np.array(target[:, 0], dtype=int) y_data = target[:, 1] ''' defining the optimisation helper functions optimize() and fitter() ''' def optimize(x_values, y_values, fitter_function): mod = lmfit.Model(fitter_function) for kwarg, (init, mini, maxi) in params_init_min_max.items(): mod.set_param_hint(str(kwarg), value=init, min=mini, max=maxi, vary=True) params = mod.make_params() return mod.fit(y_values, params, method=optim, x=x_values) def fitter(x, **kwargs): ret = simulator_model_func( model_parameters, simple_data_tokens, **kwargs) return ret['series'][full_data_tokens[0]][x] ''' run the optimisation ''' result = optimize(x_data, y_data, fitter) ''' recover and display/save optimisation results ''' opt_parameters = dict(model_parameters) opt_parameters.update(result.best_values) f = open(basename + '.res', 'w') f.write(result.fit_report()) f.write('\n\n') f.write(f'Optimal values : {result.best_values}') f.close() with open(basename + '_opt.json', 'w') as json_file: json.dump(result.best_values, json_file) json_file.close() ''' @TODO find a way to better integrate pre-existing rules and possible other confinement dates than the default ones ''' opt_rules = [r for r in model_rules] try: t_confinement = get_default_params()['other']['confinement'] opt_rules += [RuleChangeField(t_confinement, 'beta', opt_parameters['beta_post'])] except KeyError: pass try: t_deconfinement = get_default_params()['other']['deconfinement'] opt_rules += [RuleChangeField(t_deconfinement, 'beta', opt_parameters['beta_end'])] except KeyError: pass export_json(basename + '.json', opt_parameters, opt_rules)
parser.add_argument('--noplot', action='store_true', help="do not display obtained curves") parser.add_argument('-s', '--save', metavar='prefix', default='', type=str, nargs='?', help='filename prefix to output obtained curve points in .csv file format') parser.add_argument('-n', metavar='points', type=int, nargs=1, help="number of data points to consider for training") parser.add_argument('--path', metavar='pathname', type=str, nargs=1, help='to be used with -s, --save parameter. Saves output files to provided path') ''' @TODO take into account --path arguments. Current behaviour is to take default parameters and to optimise for 'SI' ''' args = parser.parse_args() default_model_params = get_default_params() day0 = default_model_params['data']['day0'] read_target = None if args.input: """@TODO consider target dates to systematically start on 01/01/2020""" read_target = pd.read_csv(args.input[0], sep=';').to_numpy() target = read_target else: default_data = default_model_params['data']['data_chu_rea'] target = np.array([[x - day0, y] for (x, y) in default_data.items() if y]).reshape([-1, 2]) if args.n: target = target[:args.n[0], ]
def model_diff(parameters: Dict[str, any], series: List[str] = None, **kwargs: Dict[str, any]) -> Dict[str, any]: parameters = dict(parameters) other_arguments = dict(kwargs) # del other_arguments['parameters'] parameters.update(other_arguments) if 't_confinement' not in parameters.keys(): t_confinement = get_default_params()['other']['confinement'] else: t_confinement = parameters['t_confinement'] if 't_end' not in parameters.keys(): t_end = get_default_params()['other']['deconfinement'] else: t_end = parameters['t_end'] if 'beta_post' not in parameters.keys(): parameters['beta_post'] = get_default_params( )['other']['r0_confinement'] / parameters['dm_r'] if 'beta_end' not in parameters.keys(): parameters['beta_end'] = 1.2 / parameters['dm_r'] r0_start = parameters['beta'] * parameters[ 'dm_r'] if 'R0_start' not in parameters.keys( ) else parameters['R0_start'] r0_confinement = parameters['beta_post'] * parameters['dm_r'] if 'R0_confinement' not in parameters.keys() else \ parameters['R0_confinement'] r0_end = parameters['beta_end'] * parameters[ 'dm_r'] if 'R0_end' not in parameters.keys() else parameters['R0_end'] gamma = 1.0 / parameters['dm_r'] # dmg dm_IR def R0(t, k: float, r0_start: float, t_confinement: int, r0_confinement: float, t_end: int, r0_end: float): # return 3.31 # return R0_start if t < t_confinement else R0_confinement # if t<(t_confinement + t_end)/2: return (r0_start - r0_confinement) / ( 1 + np.exp(-k * (-t + t_confinement))) + r0_confinement # else: # return (R0_confinement-R0_end) / (1 + np.exp(-k*(-t + t_end))) + R0_end def beta(t): k = 1.0 return R0(t, k, r0_start, t_confinement, r0_confinement, t_end, r0_end) * gamma n_population = parameters['population'] y0 = n_population - parameters['patient0'], parameters[ 'patient0'], 0.0, 0.0, 0.0, 0.0, 0.0 t = np.linspace(0, parameters['lim_time'] - 1, parameters['lim_time']) ret = odeint(deriv, y0, t, args=(beta, parameters)) se_series, incub_series, i_series, sm_series, si_series, r_series, dc_series = ret.T # R0_over_time = [beta(i) / gamma for i in range(len(t))] return { 'time': t, 'series': { 'SE': se_series, 'INCUB': incub_series, 'I': i_series, 'SM': sm_series, 'SI': si_series, 'R': r_series, 'DC': dc_series }, # 'R0': R0_over_time }