Dans l'article précédent, j'ai publié un programme qui prédit le comportement du nouveau virus corona avec le modèle SEIR. Cette fois, nous avons transformé le programme en une interface graphique, nous allons donc partager le contenu.
`Article précédent: j'ai essayé de prédire le comportement du nouveau virus corona avec le modèle SEIR. '' Lien: https://qiita.com/kotai2003/items/ed28fb723a335a873061
Actuellement, de nombreux articles de recherche ont été publiés pour estimer les paramètres SEIR à partir des cas de nouveau coronavirus. Cette fois, je vais calculer le modèle SEIR avec les estimations de paramètres publiées dans l'article publié le 16 février. (Référence 2)
Parameter | Chine continentale (à l'exclusion de la province du Hubei) | Province du Hubei (à l'exclusion de Wuhan) | Wuhan |
---|---|---|---|
Population N(million) | 1340 | 45 | 14 |
Taux d'infection[beta] | 1.0 | 1.0 | 1.0 |
Latency period (days) | 2 | 2 | 2 |
infectious_period (days) | 6.6 | 7.2 | 7.4 |
E_0 | 696 | 592 | 318 |
I_0 | 652 | 515 | 389 |
Par exemple, [Social Distance Strategy](https://ja.wikipedia.org/wiki/%E7%A4%BE%E4%BC%9A%E8%B7%9D%E9%9B%A2%E6%88%A6 Avec% E7% 95% A5), il est possible de confirmer par simulation comment le pic de personnes infectées fluctue lorsque le taux d'infection passe de 0,5 à 0,4.
main_routine.py
import tkinter as tk
from tkinter import ttk
from tkinter import Menu
from tkinter import messagebox
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from calcSEIR import SEIR_EQ
class Application(tk.Frame):
def __init__(self,master):
super().__init__(master)
self.pack()
self.master.geometry("1000x600")
self.master.title("SEIR Epidemic Model Simulator")
self.create_widgets()
def create_widgets(self):
#Canvas Frame
self.canvas_frame = tk.Frame(self)
self.canvas_frame.configure(width=600, height=480)
self.canvas_frame.grid(row=0, column=0)
self.canvas_frame.grid(padx = 20, pady=20)
#Label Frame for Input Parameters
self.frame_param = tk.LabelFrame( self )
self.frame_param.configure( text=' Input Paramaters ' )
self.frame_param.grid( row=0, column=1 )
self.frame_param.grid( padx=20, pady=20 )
#1. Population
#Label_population
self.label_popu = tk.Label( self.frame_param)
self.label_popu.configure(text ='Population (Million)')
self.label_popu.grid(row =0, column = 0)
#Scale population
self.var_popu = tk.DoubleVar() #scale variable
self.scale_popu = tk.Scale( self.frame_param)
self.scale_popu.configure(orient="horizontal")
self.scale_popu.configure(from_=1, to= 1350)
self.scale_popu.configure(variable=self.var_popu)
self.scale_popu.grid(row=0, column=1)
#2. Infection Rate
# Label_Infection_Rate
self.label_IR = tk.Label( self.frame_param )
self.label_IR.configure( text='Infection Rate' )
self.label_IR.grid( row=1, column=0 )
# Scale Infection_Rate
self.var_IR = tk.DoubleVar() # scale variable
self.scale_IR = tk.Scale( self.frame_param )
self.scale_IR.configure( orient="horizontal" )
self.scale_IR.configure( from_=0.1, to=2 , resolution=0.1)
self.scale_IR.configure( variable=self.var_IR )
self.scale_IR.grid( row=1, column=1 )
#3. Latency Period
# Label_
self.label_LP = tk.Label( self.frame_param )
self.label_LP.configure( text='Latency Period (days)' )
self.label_LP.grid( row=2, column=0 )
# Scale
self.var_LP = tk.IntVar() # scale variable
self.scale_LP = tk.Scale( self.frame_param )
self.scale_LP.configure( orient="horizontal" )
self.scale_LP.configure( from_=1, to=14 , resolution=0.1)
self.scale_LP.configure( variable=self.var_LP )
self.scale_LP.grid( row=2, column=1 )
# 3.5 Infection Period
# Label_
self.label_IP = tk.Label( self.frame_param )
self.label_IP.configure( text='Infections Period (days)' )
self.label_IP.grid( row=3, column=0 )
# Scale
self.var_IP = tk.IntVar() # scale variable
self.scale_IP = tk.Scale( self.frame_param )
self.scale_IP.configure( orient="horizontal" )
self.scale_IP.configure( from_=1, to=14, resolution=0.1 )
self.scale_IP.configure( variable=self.var_IP )
self.scale_IP.grid( row=3, column=1 )
#4 E_0
self.label_E0 = tk.Label( self.frame_param )
self.label_E0.configure( text='E(t=0)' )
self.label_E0.grid( row=4, column=0 )
#Entry
self.Entry_E0 = tk.Entry(self.frame_param)
self.Entry_E0.grid(row=4, column=1)
self.Entry_E0.insert(tk.END,"696")
#5 I_0
self.label_I0 = tk.Label( self.frame_param )
self.label_I0.configure( text='I(t=0)' )
self.label_I0.grid( row=5, column=0 )
# Entry
self.Entry_I0 = tk.Entry( self.frame_param )
self.Entry_I0.grid( row=5, column=1 )
self.Entry_I0.insert( tk.END, "652" )
#6 R_0
self.label_R0 = tk.Label( self.frame_param )
self.label_R0.configure( text='E(t=0)' )
self.label_R0.grid( row=6, column=0 )
# Entry
self.Entry_R0 = tk.Entry( self.frame_param )
self.Entry_R0.grid( row=6, column=1 )
self.Entry_R0.insert( tk.END, "0" )
#7 Time
self.label_time = tk.Label(self.frame_param)
self.label_time.configure( text = 'Time [days]')
self.label_time.grid(row=7, column=0)
self.var_time = tk.IntVar() # scale variable
self.scale_time = tk.Scale( self.frame_param )
self.scale_time.configure( orient="horizontal" )
self.scale_time.configure( from_=10, to=500, resolution=1 )
self.scale_time.configure( variable=self.var_time )
self.scale_time.grid( row=7, column=1 )
#Basic Reproduction Number
# Label Frame result
self.frame_basicR0 = tk.LabelFrame( self )
self.frame_basicR0.configure( text=' Basic Reproduction Number ' )
self.frame_basicR0.grid( row=2, column=1 )
self.frame_basicR0.grid( padx=20, pady=20 )
self.label_basicR0 = tk.Label(self.frame_basicR0)
self.label_basicR0.grid(row = 0, column=0)
self.label_basicR0.configure(text = ' R0 is ')
self.msg_basicR0 = tk.Message(self.frame_basicR0)
self.msg_basicR0.grid(row=0, column=1)
self.msg_basicR0.configure(text ='')
# Button
##Label Frame for Buttons
# Label Frame for Input Parameters
self.frame_button = tk.LabelFrame( self )
self.frame_button.configure( text=' Operation ' )
self.frame_button.grid( row=2, column=0 )
self.frame_param.grid( padx=20, pady=20 )
#button
# Plot (Rungekutta. Plot..Canvas..)
self.button_plot = tk.Button( self.frame_button )
self.button_plot.configure( text='Calculate & Plot' )
self.button_plot.grid( column=0, row=1 )
self.button_plot.configure( command=self.plotCalc )
self.button_plot.configure(width = 20, height=2)
# Quit Button
self.button_quit = tk.Button( self.frame_button )
self.button_quit.config( text='Quit' )
self.button_quit.grid( column=2, row=1 )
self.button_quit.configure( command=self.quit_app )
self.button_quit.configure( width = 15, height=2 )
## Event Call Back
def plotCalc(self):
# parameters
self.t_max = self.var_time.get() # days
self.dt = 0.01
# initial_state
self.N_pop = 1e6*self.var_popu.get()
self.E_0 = int(self.Entry_E0.get())
self.I_0 = int(self.Entry_I0.get())
self.R_0 = int(self.Entry_R0.get())
self.S_0 = self.N_pop - (self.E_0 + self.I_0 + self.R_0)
self.ini_state = [self.S_0, self.E_0, self.I_0, self.R_0] # [S[0],E,[0], I[0], R[0]]
#Taux d'infection
self.beta_const = self.var_IR.get() #Taux d'infection
#Taux d'infection après exposition
self.epsilon_const = 1 / self.var_LP.get()
#Taux de récupération et taux d'isolement
self.gamma_const = 1 / self.var_IP.get()
#Basic Reproduction number in SEIR model
self.basicR0 = self.beta_const/self.gamma_const +self.beta_const/self.epsilon_const
self.msg_basicR0.configure( text=str(self.basicR0) )
#https://www.fields.utoronto.ca/programs/scientific/10-11/drugresistance/emergence/fred1.pdf
# numerical integration
self.times = np.arange( 0, self.t_max, self.dt )
self.args = (self.beta_const, self.epsilon_const, self.gamma_const, self.N_pop)
# Numerical Solution using scipy.integrate
# Solver SEIR model
self.result = odeint(SEIR_EQ, self.ini_state, self.times, self.args )
## Plotting
# Generate Figure instance
self.fig = plt.Figure()
#Generate Axe instance
#ax1
self.ax1 = self.fig.add_subplot(111)
self.ax1.plot(self.times, self.result)
self.ax1.set_title('SEIR Epidemic model')
self.ax1.set_xlabel('time [days]')
self.ax1.set_ylabel('population [persons]')
self.ax1.legend(['Susceptible', 'Exposed', 'Infectious', 'Removed'])
self.ax1.grid()
#Link to Axe instance to Canvas
#Then show Canvas onto canvas_Frame
self.canvas = FigureCanvasTkAgg( self.fig, self.canvas_frame )
self.canvas.draw()
self.canvas.get_tk_widget().grid(column=0, row=0)
def quit_app(self):
self.Msgbox = tk.messagebox.askquestion( "Exit Applictaion", "Are you sure?", icon="warning" )
if self.Msgbox == "yes":
self.master.destroy()
else:
tk.messagebox.showinfo( "Return", "you will now return to application screen" )
def main():
root = tk.Tk()
app = Application(master=root)#Inherit
app.mainloop()
if __name__ == "__main__":
main()
calcSEIR.py
# Define differential equation of SEIR model
'''
dS/dt = -beta * S * I / N
dE/dt = beta* S * I / N - epsilon * E
dI/dt = epsilon * E - gamma * I
dR/dt = gamma * I
[v[0], v[1], v[2], v[3]]=[S, E, I, R]
dv[0]/dt = -beta * v[0] * v[2] / N
dv[1]/dt = beta * v[0] * v[2] / N - epsilon * v[1]
dv[2]/dt = epsilon * v[1] - gamma * v[2]
dv[3]/dt = gamma * v[2]
'''
def SEIR_EQ(v, t, beta, epsilon, gamma, N ):
return [-beta * v[0] * v[2] / N ,beta * v[0] * v[2] / N - epsilon * v[1],
epsilon * v[1] - gamma * v[2],gamma * v[2]]
Recommended Posts