<jupyter_start><jupyter_text>Olas epidémicasVamos a analizar diferentes escenarios, de olas epidémicas.Cada hipotesis tiene distintos escenarios.En cada hipotesis, intentaremos encontrar aquellos umbrales de confinamiento/desconfinamiento que minimicen los valores de olas, días de confinamiento, e infectados totales, por cada escenario de cada hipotesis<jupyter_code>import numpy as np
import pandas as pd 
import time
from datetime import datetime, date, time, timedelta
from IPython.display import display, HTML
import matplotlib.dates as mdates
from sklearn.model_selection import GridSearchCV,ParameterGrid
from IPython.display import display, HTML

SITUACION_INICIAL = 1
prevalencia = 0 
R0 = 5.7
DIAS_EN_REINFECTAR=5

### Calculamos la capacidad del sistema sanitario.
####Cuanto se tardaria en copar las camas de uci en cada escenario
"""
"Antes de la crisis sanitaria, España disponía de unas 4.500 camas UCI, capacidad que aumentó hasta las 8.000"
Madrid cuenta con 1.750 camas
Cataluña tiene 1.722 camas
Andalucía con 1.200 camas.
Canarias cuenta con 595 camas.
Euskadi con capacidad para 550 camas. 
Castilla-León tiene 500 camas.
Aragón con 300 camas.
Castilla-La Mancha cuenta con 300 camas.
Galicia tiene 274 camas.
Comunidad Valenciana con 254 plazas libres.
Navarra con 156 camas. 
Murcia tiene 123 camas. 
Baleares con 120 camas.
Extremadura cuenta con 100 camas.
Cantabria con 64 camas.
Asturias cuenta con 61 camas. 
La Rioja tiene 23 plazas. 
TOTAL = 8092
"""

"De los 11.424 pacientes de Covid-19 ingresados en Madrid, según datos del Ministerio de Sanidad, 1.332 están en la UCI, un 11,7%."
"Si para una prevalencia de 10% (750000 personas para la comunidad de madrid)"

# Calculamos la capacidad del sistema sanitario - el nº de enfermos que puede haber antes de que colapse
NUMERO_CAMAS_UCI=8092 

PORCENTAJE_ENFERMOS_NECESITADOS_HOSPITALIZACION = 0.088 # https://www.redaccionmedica.com/secciones/sanidad-hoy/coronavirus-en-personal-sanitario-hospitalizacion-en-el-8-8-de-casos-9925
PORCENTAJE_HOSPITALIZADOS_NECESITADOS_UCI = 0.05  #https://www.elperiodico.com/es/sociedad/20200316/coronavirus-hospitalizados-graves-contagio-7891866

CAPACIDAD_SISTEMA_SANITARIO = NUMERO_CAMAS_UCI / PORCENTAJE_ENFERMOS_NECESITADOS_HOSPITALIZACION / PORCENTAJE_HOSPITALIZADOS_NECESITADOS_UCI
CAPACIDAD_SISTEMA_SANITARIO = int(CAPACIDAD_SISTEMA_SANITARIO)

print ("La estimacion de la capacidad del sistema sanitario es " , CAPACIDAD_SISTEMA_SANITARIO ) 

def Get_Header(GENERACIONES,df,FECHA_INICIAL_STR = '2020-02-01'):
    array_fechas = []
    FECHA_INICIAL = datetime.strptime(FECHA_INICIAL_STR, "%Y-%m-%d")
    modified_date = FECHA_INICIAL
    NUM_GENERACIONES = range(1,GENERACIONES)
    for generacion in NUM_GENERACIONES:
        modified_date += timedelta(days=DIAS_EN_REINFECTAR)
        array_fechas.append(datetime.strftime(modified_date, "%Y-%m-%d"))
    df.columns = array_fechas
    return df

def Calcular_Cuadro_Prevalencias( R0,GENERACIONES,ARRAY_PREVALENCIAS, SITUACION_INICIAL=1,FECHA_INICIAL_STR = '2020-02-01',DEBUG=False):
    if DEBUG : 
        print (f""" Calcular_Cuadro_Prevalencias infectados_en_esta_generacion {R0},{GENERACIONES},{ARRAY_PREVALENCIAS}, {SITUACION_INICIAL}, {FECHA_INICIAL_STR} """)
    diccionario_prevalencias = {}
    array=[]

    for prevalencia in ARRAY_PREVALENCIAS : 
        infectados_en_esta_generacion = SITUACION_INICIAL
        NUM_GENERACIONES = range(1,GENERACIONES)
        array=[]
        for generacion in NUM_GENERACIONES:
            prevalencia_esta_iteracion =  min(45000000,np.sum(array)) / 45000000
            if DEBUG : print ("infectados_en_esta_generacion",infectados_en_esta_generacion,R0,prevalencia,prevalencia_esta_iteracion)
            infectados_en_esta_generacion = int(infectados_en_esta_generacion * R0 * max(0,( 1 - (prevalencia + prevalencia_esta_iteracion)) ) )
            array.append(infectados_en_esta_generacion)
        diccionario_prevalencias['prevalencia ' + str("{:.1f}".format(prevalencia)) + ' y R0 ' + str(R0)] = array
    df = pd.DataFrame.from_dict(diccionario_prevalencias,'index')    
    df = Get_Header(GENERACIONES,df,FECHA_INICIAL_STR)
    df = df.astype(np.int64)
    return df.T

# Auxiliary functions
def interpolate_dataframe(df,freq):
    if freq == 'H':
        rng = pd.date_range(df.index.min(), df.index.max() + pd.Timedelta(23, 'H'), freq='H')
    elif freq == 'D' :  
        rng = pd.date_range(
            datetime.strptime(str(df.index.min())[:10]+' 00:00:00', "%Y-%m-%d %H:%M:%S") ,
            datetime.strptime(str(df.index.max())[:10]+' 00:00:00', "%Y-%m-%d %H:%M:%S"), 
            freq='D')
        df.index = pd.to_datetime(df.index)  
    df2 = df.reindex(rng)
    df = df2
    for column in df.columns :
        s = pd.Series(df[column])
        s.interpolate(method="quadratic", inplace =True)
        df[column] = pd.DataFrame([s]).T
    df.index.name = 'Fecha'
    return df

# first execution
GENERACIONES=8
ARRAY_PREVALENCIAS = np.linspace(0,0.70,8)
ARRAY_PREVALENCIAS



   
from matplotlib import pyplot as plt    
import pandas as pd
import numpy as np

def Get_Chart(df, title="default", xlabel="" ):
    fig = plt.figure(figsize=(8, 6), dpi=80)

    for ca in df.columns:
        plt.plot(df[ca])
        plt.legend(df.columns)
        fig.suptitle(title, fontsize=20)
    plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%b-%d'))
    plt.gca().xaxis.set_major_locator(mdates.DayLocator(interval=7))
    plt.xticks(rotation=45)
    plt.gca().set_xlabel(xlabel)
    return plt



ARRAY_R0S = [2.7,
             3.7 ,
             4.7,
             5.7,
             6.7 ]<jupyter_output><empty_output><jupyter_text>TODO:     - Hacer gráfico de la evolución del nº de infectados, en el confinamiento (R0<1)<jupyter_code>ARRAY_R0S = [2.7,
             3.7 ,
             4.7,
             5.7,
             6.7 ]


#### PRedicciones a futuro

"""
Crear 30.
Borrar las mayores de umbral superios.
Aplicar hasta que haya menos de x
"""
from datetime import date
RO_CALOR= 1.702             
GENERACIONES=15

def calcular_prevision(**kwargs) :
    """FECHA_FINAL_STR,
    FECHA_INICIAL_STR,
    SITUACION_INICIAL,
    POBLACION_INICIAL_INFECTADA,
    R0_max,
    R0_min,
    Umbral_max,
    Umbral_min):
"""
    FECHA_FINAL_STR              = kwargs.pop('FECHA_FINAL_STR')
    FECHA_INICIAL_STR            = kwargs.pop('FECHA_INICIAL_STR')
    SITUACION_INICIAL            = kwargs.pop('SITUACION_INICIAL')
    POBLACION_INICIAL_INFECTADA  = kwargs.pop('POBLACION_INICIAL_INFECTADA')
    R0_max                       = kwargs.pop('R0_max')
    R0_min                       = kwargs.pop('R0_min')
    Umbral_max                   = kwargs.pop('Umbral_max')
    Umbral_min                   = kwargs.pop('Umbral_min')
    GENERACIONES_SUBIDA          = kwargs.pop('GENERACIONES_SUBIDA',16)
    GENERACIONES_BAJADA          = kwargs.pop('GENERACIONES_BAJADA',22)
    INCREMENTOS_IMPORTADOS_CADA_ITERACION = kwargs.pop('INCREMENTOS_IMPORTADOS_CADA_ITERACION',50)
    DEBUG                        = kwargs.pop('DEBUG',False)

    
    
    
    if DEBUG:  print(  f"""FECHA_FINAL_STR={FECHA_FINAL_STR},
        FECHA_INICIAL_STR={FECHA_INICIAL_STR},
        SITUACION_INICIAL={SITUACION_INICIAL},
        POBLACION_INICIAL_INFECTADA={POBLACION_INICIAL_INFECTADA},
        R0_max={R0_max},
        R0_min={R0_min},
        Umbral_max={Umbral_max},
        Umbral_min={Umbral_min}""")
    df_temp = pd.DataFrame()
    df = pd.DataFrame(columns = ['Infectados'])    
    
    #
    while FECHA_INICIAL_STR < FECHA_FINAL_STR :

        df_temp = pd.DataFrame()
        PREVALENCIA = (POBLACION_INICIAL_INFECTADA + df.iloc[:,0].sum()) /45000000
        ARRAY_PREVALENCIAS = []
        ARRAY_PREVALENCIAS.append(PREVALENCIA)

        # Subida
        # En verano cambian los parámetros
        PERIODO_CALOR = ( FECHA_INICIAL_STR[5:] > '06-15' ) & ( FECHA_INICIAL_STR[5:] <  '09-15' )
        R0_DESCONTADO_CALOR = min(R0_max,RO_CALOR) if PERIODO_CALOR else R0_max
        GENERACIONES_SUBIDA = 30       if PERIODO_CALOR else kwargs.pop('GENERACIONES_SUBIDA',16)

        if DEBUG:  print(f""" subida SITUACION_INICIAL={SITUACION_INICIAL},
            R0                 = {R0_DESCONTADO_CALOR} ,
            GENERACIONES       = {GENERACIONES_SUBIDA} ,
            ARRAY_PREVALENCIAS = {ARRAY_PREVALENCIAS}  ,
            FECHA_INICIAL_STR  = {FECHA_INICIAL_STR} ,
            df_shape           = {df.shape[0]}   """)
        df_temp =  Calcular_Cuadro_Prevalencias( 
            DEBUG = False,
            SITUACION_INICIAL  = SITUACION_INICIAL   ,
            R0                 = R0_DESCONTADO_CALOR ,
            GENERACIONES       = GENERACIONES_SUBIDA ,
            ARRAY_PREVALENCIAS = ARRAY_PREVALENCIAS  ,
            FECHA_INICIAL_STR  = FECHA_INICIAL_STR )  

        # Borramos las siguientes
        
        df_temp['Infectados'] = df_temp.iloc[:,0]
        df_temp = df_temp[['Infectados']]

        HACEMOS_LA_BAJADA =df_temp['Infectados'].max() > Umbral_max
        if  df_temp[(df_temp['Infectados'] > (Umbral_max*1) )].size > 0  :
            FECHA_DESDE_LA_QUE_BORRAR = df_temp[(df_temp['Infectados'] > (Umbral_max*1) )].index[0]
            otro_index = [fecha for fecha in df_temp.index if fecha < FECHA_DESDE_LA_QUE_BORRAR ]
            df_temp = df_temp.head(len(otro_index))

            df_temp.dropna()
            df_temp = df_temp.loc[~df_temp.index.duplicated(keep='last')]
            df_temp = pd.DataFrame(df_temp)

        df = pd.concat([df_temp,df])
        df = df.sort_index()

        SITUACION_INICIAL = df.iloc[-1]['Infectados']
        df.Infectados.iat[-1] += INCREMENTOS_IMPORTADOS_CADA_ITERACION
        
        # Bajada        
        if HACEMOS_LA_BAJADA :           
            PREVALENCIA = (POBLACION_INICIAL_INFECTADA + df.iloc[:,0].sum()) /45000000
            ARRAY_PREVALENCIAS = []
            ARRAY_PREVALENCIAS.append(PREVALENCIA)
            FECHA_INICIAL_STR = df.index[-1]
            df_temp = pd.DataFrame()

            if DEBUG:  print(f""" bajada SITUACION_INICIAL={SITUACION_INICIAL},
                R0                 = {R0_min} ,
                GENERACIONES       = {GENERACIONES_BAJADA} ,
                ARRAY_PREVALENCIAS = {ARRAY_PREVALENCIAS}  ,
                FECHA_INICIAL_STR  = {FECHA_INICIAL_STR} ,
                df_shape           = {df.shape[0]}   """)
            df_temp =  Calcular_Cuadro_Prevalencias(
                DEBUG              = False,
                SITUACION_INICIAL  = SITUACION_INICIAL,
                R0                 = R0_min,
                GENERACIONES       = GENERACIONES_BAJADA,
                ARRAY_PREVALENCIAS = ARRAY_PREVALENCIAS,
                FECHA_INICIAL_STR  = FECHA_INICIAL_STR )
            
            # Borramos las siguientes
            df_temp['Infectados'] = df_temp.iloc[:,0]
            df_temp = df_temp[['Infectados']]
            if  df_temp[(df_temp['Infectados'] < (Umbral_min*1) )].size > 0  :
                FECHA_DESDE_LA_QUE_BORRAR = df_temp[(df_temp['Infectados'] < (Umbral_min*1) )].index[0]
                otro_index = [fecha for fecha in df_temp.index if fecha < FECHA_DESDE_LA_QUE_BORRAR ]
                df_temp = df_temp.head(len(otro_index))
                

            df_temp = pd.DataFrame(df_temp)
            df = pd.concat([df_temp,df])
            df = df.sort_index()
            SITUACION_INICIAL = df.iloc[-1]['Infectados']
            #return df,df_temp
        FECHA_INICIAL_STR = df.index[-1]
        df.Infectados.iat[-1] += INCREMENTOS_IMPORTADOS_CADA_ITERACION
        if DEBUG:  print(f""" iteracion :  df_shape= {df.shape[0]}  ,FECHA_INICIAL_STR={FECHA_INICIAL_STR} , FECHA_FINAL_STR={FECHA_FINAL_STR}""")


            
    FECHA_DESDE_LA_QUE_BORRAR = FECHA_FINAL_STR
    otro_index = [fecha for fecha in df.index if fecha <= FECHA_DESDE_LA_QUE_BORRAR ]
    df = df.head(len(otro_index))

    df = df[df > 0].dropna()
    df = df.dropna()
    df = df.loc[~df.index.duplicated(keep='last')]
    if DEBUG:  print(f""" final :  df_shape= {df.shape[0]}  ,FECHA_INICIAL_STR={FECHA_INICIAL_STR} , FECHA_FINAL_STR={FECHA_FINAL_STR}""")
    return df 
    

"""
SITUACION_INICIAL           = 1000
POBLACION_INICIAL_INFECTADA = 4500000
R0_max                      = 5.7 
R0_min                      = 0.5
Umbral_max                  = CAPACIDAD_SISTEMA_SANITARIO 
Umbral_min                  = 10000
FECHA_INICIAL_STR           = '2020-07-01'
FECHA_FINAL_STR             = '2021-01-01'
"""
SITUACION_INICIAL =10000
POBLACION_INICIAL_INFECTADA=4500000
R0_max=5.7
R0_min=0.5
Umbral_max=1839090
Umbral_min=5000
FECHA_FINAL_STR   ='2021-07-01'
FECHA_INICIAL_STR ='2020-07-01'



df = calcular_prevision(
    FECHA_FINAL_STR = FECHA_FINAL_STR,
    FECHA_INICIAL_STR = FECHA_INICIAL_STR,
    SITUACION_INICIAL = SITUACION_INICIAL,
    POBLACION_INICIAL_INFECTADA =  POBLACION_INICIAL_INFECTADA,
    R0_max = R0_max,
    R0_min =  R0_min,
    Umbral_max =  Umbral_max,
    Umbral_min =  Umbral_min,
    DEBUG=False)

#df
# DEBUG
#SITUACION_INICIAL  = 1000
#R0_min             = 1.702 
#GENERACIONES_BAJADA= 30 
#ARRAY_PREVALENCIAS = [0.1]  
#FECHA_INICIAL_STR  = '2020-07-01'

#df_temp =  Calcular_Cuadro_Prevalencias( 
#  	R0                 = R0_min,
#	GENERACIONES       = GENERACIONES_BAJADA,
#	ARRAY_PREVALENCIAS = ARRAY_PREVALENCIAS,
#	SITUACION_INICIAL  = SITUACION_INICIAL,
#	FECHA_INICIAL_STR  = FECHA_INICIAL_STR    ,
#    DEBUG              = False )<jupyter_output><empty_output><jupyter_text>Analizamos la primera hipotesis.Que pasaría si la infectividad del virus es de una R0 de 5.7. Tenemos varios escenario de R0, con/sin mascarilla, con/sin distanciamiento.Estos son los peores escenarios.Solo confinamos cuando superamos la capacidad hospitalaria, desconfinamos hasta que llegamos a 5000 nuevas infecciones en 5 días Estos escenarios son solo una linea base, para ver cuanto optimizamos si no tomamos decisiones de confinamiento/desconfinamiento.<jupyter_code>""" diccionario_R0s = {"Infectividad con prevalencia original, R0=5.7" : { R0 : 5.7, POBLACION_INICIAL_INFECTADA : 4500000} ,  
"lo anterior + distanciamiento social efectivo , R0=3.590"  : 3.590,   
"lo anterior + uso mascarillas , R0=2.082" : 2.082   ,                 
"lo anterior + temperaturas de verano , R0=1.707" : 1.702             
}

Infectividad primera ola , R0=5.7                           223383
lo anterior + distanciamiento social efectivo , R0=3.989     83430
lo anterior + uso mascarillas , R0=2.314                     20062
lo anterior + temperaturas de verano , R0=1.897              12331
lo anterior + confinamiento , R0=0.5                           875
"""
array_parametros = [
    { "descripcion" : "Infectividad con prevalencia actual  , R0=5.13"            , 'R0' : 5.7   , 'POBLACION_INICIAL_INFECTADA' : 4500000} 
 ]
array_parametros = [
    { "descripcion" : "Infectividad con prevalencia original, R0=5.7"             , 'R0' : 5.7   , 'POBLACION_INICIAL_INFECTADA' : 0} ,
    { "descripcion" : "Infectividad con prevalencia actual  , R0=5.13"            , 'R0' : 5.7   , 'POBLACION_INICIAL_INFECTADA' : 4500000} ,
    { "descripcion" : "lo anterior + distanciamiento social efectivo  , R0=3.590" , 'R0' : 3.989 , 'POBLACION_INICIAL_INFECTADA' : 4500000} ,
    { "descripcion" : "lo anterior + uso mascarillas , R0=2.082"                  , 'R0' : 2.314 , 'POBLACION_INICIAL_INFECTADA' : 4500000} ,
]


df_array = []

dict_default_values = {
    "SITUACION_INICIAL" : 10000                        ,
    "R0_min"            :     0.5                      ,
    "Umbral_max"        :  CAPACIDAD_SISTEMA_SANITARIO , 
    "Umbral_min"        :  5000                        ,
    "FECHA_INICIAL_STR" : '2020-07-01'                 ,
    "FECHA_FINAL_STR"   : '2021-07-01'
}

def get_interpolated_days(df_temp):
    df_interpolated=interpolate_dataframe(df_temp,'D')
    return df_interpolated.shape[0] - (df_interpolated['Infectados'] - df_interpolated['Infectados'].shift(1) > 0).sum()  


for dict_escenario in array_parametros:
    ## Juntamos los valores por defecto, y los que cambian cada vez.
    param = {**dict_escenario, ** dict_default_values}
    #print(param)

    df_temp = pd.DataFrame()
    df_temp = calcular_prevision(
        FECHA_FINAL_STR             = param['FECHA_FINAL_STR'            ], 
        FECHA_INICIAL_STR           = param['FECHA_INICIAL_STR'          ], 
        SITUACION_INICIAL           = param['SITUACION_INICIAL'          ], 
        POBLACION_INICIAL_INFECTADA = param['POBLACION_INICIAL_INFECTADA'],
        R0_max                      = param['R0'                         ], 
        R0_min                      = param['R0_min'                     ], 
        Umbral_max                  = param['Umbral_max'                 ], 
        Umbral_min                  = param['Umbral_min'                 ]  ,
        DEBUG = False
    )
    df_temp
    
    df_temp = df_temp.astype(np.int64)
    df_temp = df_temp.loc[~df_temp.index.duplicated(keep='last')]
    infectados_totales = int(df_temp.astype(int).sum(axis=0))
    #print(param['descripcion'], df_temp.tail(1).index[-1],"suma: " , suma)
    df_array.append(df_temp) 
    DIAS_CONFINAMIENTO = get_interpolated_days(df_temp)

    plt = Get_Chart(df=interpolate_dataframe(df_temp,'D'), 
                    title = param['descripcion'] +" \n, "+ str(infectados_totales/1000000)[:4] + " millones infectados, " +  str(DIAS_CONFINAMIENTO) + ", dias de confinamiento." ) 
    plt.gca().xaxis.set_major_locator(mdates.DayLocator(interval=14))

    ax = plt.gca()
    ax.set_ylim([0,Umbral_max*2])
    param = {}
    
df  =  pd.concat(df_array)
#df_temp
##### de aqui a abajo, solo debug

#SITUACION_INICIAL=829339
#R0                 = 5.7 
#GENERACIONES       = 15        
#ARRAY_PREVALENCIAS = [0.10]  
#FECHA_INICIAL_STR  = '2020-10-04'
            
#Calcular_Cuadro_Prevalencias( SITUACION_INICIAL  = SITUACION_INICIAL   ,
#            R0                 = R0 ,
#            GENERACIONES       = GENERACIONES        ,
#            ARRAY_PREVALENCIAS = ARRAY_PREVALENCIAS  ,
#            FECHA_INICIAL_STR  = FECHA_INICIAL_STR )

import pickle

def simulation_save_to_file(objeto,nombre_fichero):
    pickle.dump(objeto, open(nombre_fichero, 'wb'))

def simulation_get_from_file(nombre_fichero):
    return pickle.load(open(nombre_fichero, 'rb'))



def get_results_singlechart_simulacion(results_array,criterio,puesto,mejores_resultados=True):
    df_results = pd.DataFrame(results_array)
    df_results.sort_values(criterio, inplace=True,ascending=mejores_resultados)
    row     = df_results.iloc[puesto]

    ### Get Parameters from simulation
    df_temp            = pd.DataFrame(row.df)
    suma               = row.infectados_totales
    dias_confinamiento = row.dias_confinamiento
    infectados_totales = '%.2f' % ( row.infectados_totales /1000000)
    numero_de_olas     = row['numero_de_olas']
    descripcion        = row['descripcion']
    umbral_maximo      = row['Umbral_max']
    umbral_minimo      = row['Umbral_min']
    
    lugar = int(puesto) + int(1)
    df_array.append(df_temp) 
    #print (f"""criterio: {criterio}, puesto: {lugar}, descripcion {descripcion}, umbral_maximo: {umbral_maximo},umbral_minimo: {umbral_minimo}, 
    #infectados_totales: {infectados_totales}, dias_confinamiento: {dias_confinamiento}, numero_de_olas: {numero_de_olas})
    #""" )
    plt = Get_Chart(df=interpolate_dataframe(df_temp,'D'), 
                title  = f"""{descripcion}, {lugar}º en {criterio}""",
                xlabel = f"""infectados: {infectados_totales}, dias de confinamiento: {dias_confinamiento},Umbrales: ({umbral_maximo},{umbral_minimo}), olas {numero_de_olas}""")

    #plt.gca().xaxis.set_major_locator(mdates.DayLocator(interval=14))
    return plt

import matplotlib.pyplot as plt
import pandas as pd 
import matplotlib.dates as mdates

def Get_Chart2(df, title="default", xlabel="", ax=None,f=None):
    if ax is None:
        ax = plt.gca()
    plt.axes(ax)
    for ca in df.columns:
        plt.plot(df[ca])
        plt.legend(df.columns)
        f.suptitle(title, fontsize=20)
    ax.xaxis.set_major_formatter(mdates.DateFormatter('%b-%d'))
    ax.xaxis.set_major_locator(mdates.DayLocator(interval=90))
    plt.xticks(rotation=45)
    plt.gca().set_xlabel(xlabel,horizontalalignment='center')
    return plt


def get_results_multichart_simulacion2(f, axes,results_array,criterio,puesto,mejores_resultados=True):

    df_results = pd.DataFrame(results_array)
    for puesto in range(puesto): 
        df_results.sort_values(criterio, inplace=True,ascending=mejores_resultados)
        row     = df_results.iloc[puesto]

        ### Get Parameters from simulation
        df_temp            = pd.DataFrame(row.df)
        suma               = row.infectados_totales
        dias_confinamiento = row.dias_confinamiento
        infectados_totales = '%.2f' % ( row.infectados_totales /1000000)
        numero_de_olas     = row['numero_de_olas']
        descripcion        = row['descripcion']
        umbral_maximo      = row['Umbral_max']
        umbral_minimo      = row['Umbral_min']
    
        lugar = int(puesto) + int(1)


        plt = Get_Chart2( ax=axes[puesto],f=f, df=interpolate_dataframe(df_temp,'D'), 
                    title  = f"""{descripcion}, {lugar} mejores resultados en {criterio}""",
xlabel = f"""infectados: {infectados_totales} mill.,  olas {numero_de_olas}
dias de confinamiento: {dias_confinamiento},
Umbrales confinar/desconfinar: ({umbral_maximo},{umbral_minimo})""")

    return plt
"""
for criterio in ['dias_confinamiento','numero_de_olas','infectados_totales']:
    f, axes = plt.subplots(1 , 4 ,figsize=(16, 4), sharex=True)

    get_results_multichart_simulacion2(f=f, axes=axes,results_array=results_array,
                             criterio =criterio,
                            puesto=4
                            )
"""
import pickle
from tqdm.notebook import tqdm


def generate_results_simlation(dict_escenario={ "descripcion" : "Infectividad con prevalencia actual  , R0=5.13"            , 'R0' : 5.7   , 'POBLACION_INICIAL_INFECTADA' : 4500000}) :
    df_array = []

    dict_default_values = {
        "SITUACION_INICIAL" : 10000                        ,
        "R0_min"            :     0.5                      ,
        "FECHA_INICIAL_STR" : '2020-07-01'                 ,
        "FECHA_FINAL_STR"   : '2021-07-01'
    }

    grid = ParameterGrid({"Umbral_max": [1800000, 
                                         1000000,
                                          500000,
                                          250000,
                                          125000,
                                          62000,
                                         ],
 #                         "Umbral_min": [5000] } )
                           "Umbral_min": [5000, 10000,20000,40000,50000] } )

     

    results_array = [ ]

    for grid_params in grid: 
        if grid_params['Umbral_max'] <  grid_params['Umbral_min']           : continue
        if (grid_params['Umbral_max'] / grid_params['Umbral_min']) <= 2.50  : continue
        if (grid_params['Umbral_max'] - grid_params['Umbral_min']) < 25000  : continue

        ## Juntamos los valores por defecto, y los que cambian cada vez.
        params = {**grid_params, **dict_escenario, ** dict_default_values}
        #print(grid_params,dict_escenario["descripcion"])
        this_iteration_result = {}
        df_temp = pd.DataFrame()
        df_temp = calcular_prevision(
            FECHA_INICIAL_STR           = params['FECHA_INICIAL_STR'          ], 
            FECHA_FINAL_STR             = params['FECHA_FINAL_STR'            ], 
            SITUACION_INICIAL           = params['SITUACION_INICIAL'          ], 
            POBLACION_INICIAL_INFECTADA = params['POBLACION_INICIAL_INFECTADA'],
            R0_max                      = params['R0'                         ], 
            R0_min                      = params['R0_min'                     ], 
            Umbral_max                  = params['Umbral_max'                 ], 
            Umbral_min                  = params['Umbral_min'                 ]  
        )
        # Prepare results
        # Dataframe level
        df_temp = df_temp.astype(np.int64)
        df_temp = df_temp.loc[~df_temp.index.duplicated(keep='last')]
        # Calculate results
        infectados_totales = int(df_temp.astype(int).sum(axis=0))
        df_temp['Diferencia'] =  df_temp['Infectados'] - df_temp['Infectados'].shift(1)

        dias_confinamiento = get_interpolated_days(df_temp)

        numero_de_olas = (( df_temp['Diferencia'] < 0) & (df_temp['Diferencia'].shift(1) > 0 )  ).sum()   
        # Store results
        this_iteration_result['descripcion']        = dict_escenario["descripcion"]
        this_iteration_result['Umbral_max']         = params['Umbral_max']
        this_iteration_result['Umbral_min']         = params['Umbral_min']
        this_iteration_result['dias_confinamiento'] = dias_confinamiento
        this_iteration_result['numero_de_olas'    ] = numero_de_olas
        this_iteration_result['infectados_totales'] = infectados_totales
        this_iteration_result['R0']                 = params['R0']
        this_iteration_result['R0_min']             = params['R0_min']
        this_iteration_result['FECHA_INICIAL_STR']  = params['FECHA_INICIAL_STR']
        this_iteration_result['FECHA_FINAL_STR']    = params['FECHA_FINAL_STR']
        this_iteration_result['SITUACION_INICIAL']  = params['SITUACION_INICIAL']
        this_iteration_result['POBLACION_INICIAL_INFECTADA'] = params['POBLACION_INICIAL_INFECTADA']
        this_iteration_result['df']                 = df_temp['Infectados']
          
        #print(this_iteration_result)
        results_array.append(this_iteration_result) 
    return results_array

def simulation_save_to_file(objeto,nombre_fichero):
    pickle.dump(objeto, open(nombre_fichero, 'wb'))




def Testar_Conjunto_Escenarios(array_parametros,title):
    display(HTML("<h1>"+title+"</h1>"))

    all_results_array=[]
    # Por cada escenario, generamos las respuestas, y obtenemos las mejores por     dias_confinamiento','numero_de_olas','infectados_totales'
    for i,escenario in  tqdm(enumerate(array_parametros), desc="Procesando escenarios") :
        results_array = []    
        results_array = generate_results_simlation(escenario)
        all_results_array += results_array
        print(" Escenario: "+ escenario['descripcion'])

        simulation_save_to_file(results_array,"simulacion_"+str(i)+".pickle")
        for criterio in ['dias_confinamiento','numero_de_olas','infectados_totales']:
            f, axes = plt.subplots(1 , 4 ,figsize=(16, 4), sharex=True)

            get_results_multichart_simulacion2(f=f, axes=axes,results_array=results_array,
                                     criterio =criterio,
                                    puesto=4
                                    )

    simulation_save_to_file(all_results_array,"last_scenary_all.pickle")
 
array_parametros_estudio_mascarillas = [
    { "descripcion" : "Infectividad con prevalencia original, R0=5.7"             , 'R0' : 5.7   , 'POBLACION_INICIAL_INFECTADA' : 0} ,
    { "descripcion" : "Infectividad con prevalencia actual  , R0=5.13"            , 'R0' : 5.7   , 'POBLACION_INICIAL_INFECTADA' : 4500000} ,
    { "descripcion" : "lo anterior + distanciamiento social efectivo  , R0=3.590" , 'R0' : 3.989 , 'POBLACION_INICIAL_INFECTADA' : 4500000} ,
    { "descripcion" : "lo anterior + distanciamiento social lejania   , R0=2.836" , 'R0' : 3.1515 , 'POBLACION_INICIAL_INFECTADA' : 4500000} ,
    { "descripcion" : "lo anterior + uso mascarillas , R0=2.082"                  , 'R0' : 2.314 , 'POBLACION_INICIAL_INFECTADA' : 4500000} ,
]




Testar_Conjunto_Escenarios(array_parametros_estudio_mascarillas,"Estudio de Mascarillas")<jupyter_output><empty_output><jupyter_text>Segunda hipotesis Que el virus sea aerotransportadoEs decir, que la capacidad principal de propagación del virus sea a traves del aire.De ser esto cierto, las mascarillas jugarían un papel fundamental.Esta hipotesis sigue este estudio https://www.pnas.org/content/early/2020/06/10/2009637117, y las R0 son calculadas a partir del mismo<jupyter_code>array_parametros_airborne = [
    { "descripcion" : "Airborne Mascarillas 50%, R0=1.35"             , 'R0' : 1.35   , 'POBLACION_INICIAL_INFECTADA' : 4500000 , 'GENERACIONES_SUBIDA' : 25 , 'GENERACIONES_BAJADA' : 25} ,
    { "descripcion" : "Airborne Mascarillas 70%, R0=1.02"            , 'R0' : 1.02   , 'POBLACION_INICIAL_INFECTADA' : 4500000 , 'GENERACIONES_SUBIDA' : 25 , 'GENERACIONES_BAJADA' : 25} ,
    
]
Testar_Conjunto_Escenarios(array_parametros_airborne,"Analisis airborne medio de transporte")<jupyter_output><empty_output><jupyter_text>Conclusiones del estudio de la hipotesis, el virus es aerotransportado.TO-DO<jupyter_code># Funciones de debug
import janitor
df_results = pd.DataFrame(results_array)
df_results
df  = pd.DataFrame(simulation_get_from_file('simulacion_all.pickle'))
df_extract =pd.DataFrame(
    df
    .filter_on('descripcion == "lo anterior + uso mascarillas , R0=2.082"'  )
    .filter_on('Umbral_max == 125000'  )
    .filter_on('Umbral_min == 5000'  )
    [['df']]
)
pd.set_option('display.max_rows', 365)

df_temp = pd.DataFrame(df_extract.df.iloc[0])
#df_temp<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10510051616408585, 'fraction_numerical': 0.03361858190709047, 'mean_word_length': 2.703810841403597, 'pattern_counts': {'":': 3, '<': 35, '<?xml version=': 0, '>': 32, 'https://': 3, 'lorem ipsum': 0, 'www.': 3, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 18, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '128846', 'license': 'CC-BY-4.0', 'n_tokens_mistral': 11728, 'n_tokens_neox': 10692, 'n_words': 1714, 'path': 'jupyter/.ipynb_checkpoints/Prevalencia-test-Copy1-checkpoint.ipynb', 'repo_name': 'jaimevalero/COVID-19', 'size': '29448'}