def _simul_con_extern(extern, ref, var_ref='Vacío', fecha=True): f_inic = '2000-01-01' if fecha else None res = ModeloPrueba(unid_tiempo='días').simular(t=EspecTiempo( 10, f_inic=f_inic), extern=extern) npt.assert_equal(res[var_ref].vals.values.reshape(np.array(ref).shape), ref)
def test_diario(símismo): mod = ModeloPrueba(unid_tiempo='días') mod.conectar_var_clima('Vacío', 'بارش', conv=1, combin='total') res = mod.simular(EspecTiempo(100, f_inic=símismo.fechas[0]), clima=símismo.clima, vars_interés='Vacío') npt.assert_equal(res['Vacío'].vals[:, 0], símismo.lluvia[:101])
def test_simul_guardar_cada_2(símismo): for nmb, mod in símismo.modelos.items(): with símismo.subTest(mod=nmb): res_paso_1 = símismo.res[nmb]['Lago'].vals.values[::2] res_paso_2 = mod.simular(t=EspecTiempo(200, guardar_cada=2), extern=símismo.vals_inic, vars_interés=['Lago' ])['Lago'].vals.values npt.assert_equal(res_paso_1, res_paso_2)
def test_simul_con_paso_2(símismo): for nmb, mod in símismo.modelos.items(): with símismo.subTest(mod=nmb): res_paso_1 = símismo.res[nmb]['Lago'].vals.values[::2] res_paso_2 = mod.simular(t=EspecTiempo(100, tmñ_paso=2), extern=símismo.vals_inic, vars_interés=['Lago' ])['Lago'].vals.values npt.assert_allclose(res_paso_2, res_paso_1, rtol=0.001)
def test_guardar_cada_con_fecha(símismo): mod = ModeloPrueba(unid_tiempo='días') res = mod.simular( t=EspecTiempo(10, '2001-01-01', guardar_cada=2))['Escala'] npt.assert_equal(res.vals, np.arange(11, step=2).reshape((6, 1))) pdt.assert_index_equal(res.vals.indexes[_('fecha')], pd.date_range('2001-01-01', periods=6, freq='2D'), check_names=False)
def test_anual(símismo): mod = ModeloPrueba(unid_tiempo='año') mod.conectar_var_clima('Vacío', 'بارش', conv=1, combin='total') res = mod.simular(EspecTiempo(2, f_inic=símismo.fechas[0]), clima=símismo.clima, vars_interés='Vacío') ref = np.array([ np.sum(x) for x in [ símismo.lluvia[:366], símismo.lluvia[366:366 + 365], símismo.lluvia[366 + 365:366 + 365 + 365] ] ]) npt.assert_equal(res['Vacío'].vals[:, 0], ref)
def test_bloques(símismo): tmñ_bloques = [4, 5, 3] mod = EjBloques(tmñ_bloques=tmñ_bloques, unid_tiempo='meses') mod.conectar_var_clima('ingreso_paso', 'بارش', conv=1, combin='total') mod.conectar_var_clima('ingreso_bloque', 'بارش', conv=1, combin='total') mod.conectar_var_clima('ingreso_ciclo', 'بارش', conv=1, combin='total') n_días = [ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ] sum_cum = np.cumsum(np.append([0], n_días)) ref_paso = np.array([ np.sum(símismo.lluvia[sum_cum[x]:sum_cum[x + 1]]) for x in range(24) ]) sum_cum_bloq = np.cumsum(np.append([0], np.tile(tmñ_bloques, 2))) ref_bloques = np.repeat( np.array([ np.sum( símismo. lluvia[sum_cum[sum_cum_bloq[i]]:sum_cum[sum_cum_bloq[i + 1]]]) for i in range(len(sum_cum_bloq) - 1) ]), np.tile(tmñ_bloques, 2)) ref_ciclo = np.empty(24) ref_ciclo[:12] = np.sum(símismo.lluvia[:np.sum(n_días[:12])]) ref_ciclo[12:] = np.sum(símismo.lluvia[np.sum(n_días[:12]):]) pruebas = { 'ingreso_ciclo': ref_ciclo, 'ingreso_paso': ref_paso, 'ingreso_bloque': ref_bloques } res = mod.simular(EspecTiempo(23, f_inic=símismo.fechas[0]), clima=símismo.clima) for prb, ref in pruebas.items(): if prb in ['ingreso_paso', 'ingreso_bloque']: continue with símismo.subTest(prb): npt.assert_equal(res[prb].vals[:, 0].values, ref)
def test_mensual(símismo): mod = ModeloPrueba(unid_tiempo='mes') mod.conectar_var_clima('Vacío', 'بارش', conv=1, combin='suma') res = mod.simular(EspecTiempo(2, f_inic=símismo.fechas[0]), clima=símismo.clima, vars_interés='Vacío') ref = np.array([ np.sum(x) for x in [ símismo.lluvia[:31], símismo.lluvia[31:31 + 29], símismo.lluvia[31 + 29:31 + 29 + 31] ] ]) npt.assert_equal(res['Vacío'].vals[:, 0], ref)
def test_deter(símismo): mod = EjDeterminado(tmñ_ciclo=30, unid_tiempo='días') mod.conectar_var_clima('ingreso_ciclo', 'بارش', conv=1, combin='total') mod.conectar_var_clima('ingreso_paso', 'بارش', conv=1, combin='total') ref_paso = símismo.lluvia[:360] ref_ciclo = np.repeat( np.array([ np.sum(símismo.lluvia[x * 30:x * 30 + 30]) for x in range(12) ]), 30) pruebas = {'ingreso_ciclo': ref_ciclo, 'ingreso_paso': ref_paso} res = mod.simular(EspecTiempo(30 * 12 - 1, f_inic=símismo.fechas[0]), clima=símismo.clima) for prb, ref in pruebas.items(): if prb == 'ingreso_paso': continue with símismo.subTest(prb): npt.assert_equal(res[prb].vals[:, 0].values, ref)
def validar(símismo, t, datos, paráms=None, funcs=None, vars_extern=None, corresp_vars=None): """ Efectua la validación. Parameters ---------- t: int or EspecTiempo La especificación de tiempo para la validación. datos: xr.Dataset or xr.DataArray or str or pd.DataFrame or dict or Fuente or list La base de datos para la validación. paráms: dict Diccionario de los parámetros calibrados para cada lugar. funcs: list Funciones de validación para aplicar a los resultados. vars_extern: str or list or Variable Variable(s) exógenos cuyos valores se tomarán de la base de datos para alimentar la simulación y con los cuales por supuesto no se validará el modelo. corresp_vars: Diccionario de correspondencia entre nombres de valores en el modelo y en la base de datos. Returns ------- dict Validación por variable. """ t = t if isinstance(t, EspecTiempo) else EspecTiempo(t) if not isinstance(datos, xr.Dataset): datos = datos if isinstance(datos, BD) else BD(datos) datos = datos.obt_vals( buscar_vars_interés(símismo.mod, datos, corresp_vars)) funcs = funcs or list(eval_funcs) vars_extern = vars_extern or [] if not isinstance(vars_extern, list): vars_extern = [vars_extern] vars_interés = buscar_vars_interés(símismo.mod, datos, corresp_vars) vars_valid = [v for v in vars_interés if v not in vars_extern] vals_extern = datos[list( {_resolver_var(v, corresp_vars) for v in vars_extern})] extern = { vr: vals_extern[_resolver_var(vr, corresp_vars)].dropna('n') for vr in vars_extern } extern = {ll: v for ll, v in extern.items() if v.sizes['n']} res = símismo.mod.simular(t=t, extern={ **paráms, **extern }, vars_interés=vars_valid) vals_calib = datos[list( {_resolver_var(v, corresp_vars) for v in vars_valid})] # Para hacer: si implementamos Dataset en ResultadosSimul este se puede combinar en una línea valid = {} for r in res: vr_datos = _resolver_var(str(r), corresp_vars) vals_calib_vr = vals_calib[vr_datos].dropna('n') if vals_calib_vr.sizes['n']: eje = r.vals[_('fecha')].values eje_obs = pd.to_datetime(vals_calib_vr[_('fecha')].values) eje_res = relativizar_eje(eje, eje_obs) buenas_fechas = xr.DataArray(np.logical_and( eje_res[0] <= eje_obs, eje_obs <= eje_res[-1]), dims='n') datos_r = vals_calib_vr.where(buenas_fechas, drop=True).dropna('n') if datos_r.sizes['n'] > 1: fechas_obs = datos_r[_('fecha')] interpoladas = r.interpolar(fechas=fechas_obs) valid[str(r)] = _valid_res( datos_r.values, interpoladas.values, pd.to_datetime(datos_r[_('fecha')].values), funcs) return valid
def validar(símismo, t, datos, paráms=None, funcs=None, vars_extern=None, corresp_vars=None, clima=None): """ Efectua la validación. Parameters ---------- t: int or EspecTiempo La especificación de tiempo para la validación. datos: xr.Dataset or xr.DataArray or str or pd.DataFrame or dict or Fuente or list La base de datos para la validación. paráms: dict Diccionario de los parámetros calibrados para cada lugar. funcs: list Funciones de validación para aplicar a los resultados. vars_extern: str or list or Variable Variable(s) exógenos cuyos valores se tomarán de la base de datos para alimentar la simulación y con los cuales por supuesto no se validará el modelo. corresp_vars: Diccionario de correspondencia entre nombres de valores en el modelo y en la base de datos. Returns ------- dict Validación por variable. """ t = t if isinstance(t, EspecTiempo) else EspecTiempo(t) if not isinstance(datos, pd.DataFrame): datos = datos if isinstance(datos, BD) else BD(datos) datos = datos.obt_vals( buscar_vars_interés(símismo.mod, datos, corresp_vars)) funcs = funcs or list(eval_funcs) vars_extern = vars_extern or [] if not isinstance(vars_extern, list): vars_extern = [vars_extern] vars_interés = buscar_vars_interés(símismo.mod, datos, corresp_vars) vars_valid = [v for v in vars_interés if v not in vars_extern] vals_extern = datos[ list({_resolver_var(v, corresp_vars) for v in vars_extern}) + [_('fecha')]] # Para hacer: inter y extrapolación como opción en todas simulaciones, y extrapolación con función según líms if not np.datetime64(t.f_inic) in vals_extern[_('fecha')].values: vals_extern = vals_extern.append( {_('fecha'): pd.to_datetime(t.f_inic)}, ignore_index=True) vals_extern = vals_extern.sort_values(_('fecha')) vals_extern = vals_extern.interpolate(limit_area='inside').bfill() vals_extern = vals_extern.set_index(_('fecha')) extern = { vr: vals_extern[_resolver_var(vr, corresp_vars)].dropna() for vr in vars_extern } extern = {ll: v for ll, v in extern.items() if len(v)} res = símismo.mod.simular(t=t, extern={ **paráms, **extern }, vars_interés=vars_valid, clima=clima) vals_calib = datos[ list({_resolver_var(v, corresp_vars) for v in vars_valid}) + [_('fecha')]] # Para hacer: inter y extrapolación como opción en todas simulaciones, y extrapolación con función según líms if not np.datetime64(t.f_inic) in vals_calib[_('fecha')].values: vals_calib = vals_calib.append( {_('fecha'): pd.to_datetime(t.f_inic)}, ignore_index=True) vals_calib = vals_calib.sort_values(_('fecha')) vals_calib_interp = vals_calib.interpolate( limit_area='inside').set_index(_('fecha')) vals_calib = vals_calib.set_index(_('fecha')) vals_calib.loc[t.f_inic] = vals_calib_interp.loc[t.f_inic] # Para hacer: si implementamos Dataset en ResultadosSimul este se puede combinar en una línea valid = {} for r in res: vr_datos = _resolver_var(str(r), corresp_vars) vals_calib_vr = vals_calib[vr_datos].dropna() if len(vals_calib_vr): eje = r.vals[_('fecha')].values eje_obs = pd.to_datetime(vals_calib_vr.index.values) eje_res = relativizar_eje(eje, eje_obs) buenas_fechas = np.logical_and(eje_res[0] <= eje_obs, eje_obs <= eje_res[-1]) datos_r = vals_calib_vr[buenas_fechas] if len(datos_r) > 1: fechas_obs = datos_r.index interpoladas = r.interpolar(fechas=fechas_obs) buenas = np.isfinite( r.interpolar(fechas=fechas_obs)).values[:, 0] valid[str(r)] = _valid_res(datos_r.values[buenas], interpoladas.values[buenas], datos_r.index[buenas], funcs) return valid
def test_guardar_cada(símismo): mod = ModeloPrueba() res = mod.simular(t=EspecTiempo(10, guardar_cada=2))['Escala'] npt.assert_equal(res.vals, np.arange(11, step=2).reshape((6, 1))) npt.assert_equal(res.t.eje(), np.arange(11, step=2))
def test_paso_inválido(símismo): mod = ModeloPrueba() with símismo.assertRaises(ValueError): mod.simular(EspecTiempo(100, tmñ_paso=0))
def test_paso(símismo): mod = ModeloPrueba() res = mod.simular(t=EspecTiempo(10, tmñ_paso=2))['Escala'] npt.assert_equal(res.vals, np.arange(21, step=2).reshape((11, 1))) npt.assert_equal(res.vals.indexes[_('fecha')], np.arange(21, step=2))
def test_simular_t_fecha(símismo): mod = ModeloPrueba(unid_tiempo='días') res = mod.simular(t=EspecTiempo(10, '2001-01-01'))['Escala'] pdt.assert_index_equal(res.vals.indexes[_('fecha')], pd.date_range('2001-01-01', periods=11), check_names=False)
def test_t_numérico_extern_fecha(símismo): extern = pd.DataFrame(data={'Vacío': np.arange(4)}, index=pd.date_range('2000-01-02', '2000-01-05')) with símismo.assertRaises(TypeError): ModeloPrueba(unid_tiempo='días').simular(t=EspecTiempo(10), extern=extern)