def inic_modelo(mod, paso, n_pasos, nombre_corrida): nombre_corrida = _verificar_nombre(nombre_corrida) # Establecer el nombre de la corrida. cmd_vensim(func=mod.vensim_command, args="SIMULATE>RUNNAME|%s" % nombre_corrida, mensaje_error=_('Error iniciando la corrida Vensim.')) # Establecer el tiempo final. cmd_vensim( func=mod.vensim_command, args='SIMULATE>SETVAL|%s = %i' % ('FINAL TIME', n_pasos + 1), mensaje_error=_('Error estableciendo el tiempo final para Vensim.')) # Iniciar la simulación en modo juego ("Game"). Esto permitirá la actualización de los valores de los variables # a través de la simulación. cmd_vensim(func=mod.vensim_command, args="MENU>GAME", mensaje_error=_('Error inicializando el juego Vensim.')) # Es ABSOLUTAMENTE necesario establecer el intervalo del juego aquí. Sino, no reinicializa el paso # correctamente entre varias corridas (aún modelos) distintas. cmd_vensim(func=mod.vensim_command, args="GAME>GAMEINTERVAL|%i" % paso, mensaje_error=_('Error estableciendo el paso de Vensim.'))
def cmd_vensim(func, args, mensaje_error=None, val_error=None): # pragma: sin cobertura """ Esta función sirve para llamar todo tipo_mod de comanda Vensim. Parameters ---------- func: callable La función DLL a llamar. args: list | str Los argumento a pasar a la función. Si no hay, usar una lista vacía. mensaje_error: str El mensaje de error para mostrar si hay un error en la comanda. val_error: int Un valor de regreso Vensim que indica un error para esta función. Si se deja ``None``, todos valores que no son 1 se considerarán como erróneas. Returns ------- int El código devuelto por Vensim. """ # Asegurarse que args es una lista if type(args) is not list: args = [args] # Encodar en bytes todos los argumentos de texto. for n, a in enumerate(args): if type(a) is str: args[n] = a.encode() # Llamar la función Vensim y guardar el resultado. try: resultado = func(*args) except OSError: try: resultado = func(*args) except OSError as e: raise OSError(e) # Verificar su hubo un error. if val_error is None: error = (resultado != 1) else: error = (resultado == val_error) # Si hubo un error, avisar el usuario. if error: if mensaje_error is None: mensaje_error = _('Error con la comanda Vensim.') mensaje_error += _(' Código de error {}.').format(resultado) raise ValueError(mensaje_error) # Devolver el valor devuelto por la función Vensim return resultado
def interpolar(símismo, vars_interés, lugares=None, fechas=None, extrap=False): """ Interpola datos por fecha, tomando el lugar en cuenta. Parameters ---------- vars_interés: str or list Los variables de interés. lugares: list Lugares de interés. fechas: list or str or datetime.datetime Las fechas de interés. extrap: bool Si hay que extrapolar también. Returns ------- xr.DataArray, xr.Dataset ``xr.DataArray`` si ``vars_interés`` es ``str``, ``xr.Dataset`` si ``vars_interés`` es ``list``. """ datos = símismo.obt_vals(vars_interés=vars_interés, lugares=lugares) if datos['n'].size: datos = _interpolar_xr(datos, fechas=fechas) if extrap: datos = datos.bfill(_('fecha')) datos = datos.ffill(_('fecha')) return datos
def _generar_mod(símismo, archivo, **ops_mód): try: dll_vensim = ops_mód['dll_Vensim'] except KeyError: dll_vensim = None # Llamar el DLL de Vensim. if dll_vensim is None: lugares_probables = [ 'C:\\Windows\\System32\\vendll32.dll', 'C:\\Windows\\SysWOW64\\vendll32.dll' ] arch_dll_vensim = símismo._obt_val_config( llave='dll_Vensim', cond=os.path.isfile, respaldo=lugares_probables ) if arch_dll_vensim is None: dll = None else: dll = crear_dll_vensim(arch_dll_vensim) else: dll = crear_dll_vensim(dll_vensim) nmbr, ext = os.path.splitext(archivo) if ext == '.mdl': símismo.tipo_mod = '.mdl' if dll is not None: # Únicamente recrear el archivo .vpm si necesario if not os.path.isfile(nmbr + '.vpm') or (os.path.getmtime(nmbr + '.vpm') < os.path.getmtime(archivo)): símismo.publicar_modelo(dll=dll) archivo = nmbr + '.vpm' elif ext == '.vpm': símismo.tipo_mod = '.vpm' else: raise ValueError( _('Vensim no sabe leer modelos del formato "{}". Debes darle un modelo ".mdl" o ".vpm".') .format(ext) ) if dll is None: return # Inicializar Vensim cmd_vensim(func=dll.vensim_command, args=[''], mensaje_error=_('Error iniciando Vensim.')) # Cargar el modelo cmd_vensim(func=dll.vensim_command, args='SPECIAL>LOADMODEL|%s' % archivo, mensaje_error=_('Error cargando el modelo de Vensim.')) # Parámetros estéticos de ejecución. cmd_vensim(func=dll.vensim_be_quiet, args=[2], mensaje_error=_('Error en la comanda "vensim_be_quiet".'), val_error=-1) return dll
def leer_resultados(símismo, var=None, corrida=None): if corrida is None: if símismo.corrida_activa is None: raise ValueError(_('Debes especificar una corrida.')) else: corrida = símismo.corrida_activa if var in símismo.variables: try: return super().leer_resultados(var=var, corrida=corrida) except ValueError: pass mod, v = símismo.resolver_nombre_var(var) if mod in símismo.modelos and v in símismo.modelos[mod].variables: try: return símismo.modelos[mod].leer_resultados(var=v, corrida=corrida) except FileNotFoundError: pass else: var_compl = next( ('{}_{}'.format(m, var) for m in símismo.modelos if '{}_{}'.format(m, var) in símismo.mem_vars), None) if var_compl is not None: return super().leer_resultados(var=var_compl, corrida=corrida) for obj_m in símismo.modelos.values(): if var in obj_m.variables: try: return obj_m.leer_resultados(var=var, corrida=corrida) except FileNotFoundError: pass raise FileNotFoundError(_('Ningún de los submodelos pudieron leer los resultados de la corrida.'))
def obt_vars(mod): l_nombres = [] for t in [1, 2, 4, 5, 12]: mem = ctypes.create_string_buffer(0) # Crear una memoria intermedia # Verificar el tamaño necesario tamaño_nec = cmd_vensim( func=mod.vensim_get_varnames, args=['*', t, mem, 0], mensaje_error=_( 'Error obteniendo eñ tamaño de los variables Vensim.'), val_error=-1) mem = ctypes.create_string_buffer( tamaño_nec) # Una memoria intermedia con el tamaño apropiado # Guardar y decodar los nombres de los variables. cmd_vensim( func=mod.vensim_get_varnames, args=['*', t, mem, tamaño_nec], mensaje_error=_( 'Error obteniendo los nombres de los variables de Vensim.'), val_error=-1) l_nombres += [ x for x in mem.raw.decode().split('\x00') if x and x not in ['FINAL TIME', 'TIME STEP', 'INITIAL TIME', 'SAVEPER', 'Time'] ] return l_nombres
def cargar_mod_vensim(mod, archivo): nmbr, ext = os.path.splitext(archivo) if ext == '.mdl': # Únicamente recrear el archivo .vpm si necesario if not os.path.isfile(nmbr + '.vpm') or arch_más_recién( archivo, nmbr + '.vpm'): publicar_modelo(mod=mod, archivo=archivo) archivo = nmbr + '.vpm' elif ext != '.vpm': raise ValueError( _('Vensim no sabe leer modelos del formato "{}". Debes darle un modelo ".mdl" o ".vpm".' ).format(ext)) # Inicializar Vensim cmd_vensim(func=mod.vensim_command, args=[''], mensaje_error=_('Error iniciando Vensim.')) # Cargar el modelo cmd_vensim(func=mod.vensim_command, args='SPECIAL>LOADMODEL|%s' % archivo, mensaje_error=_('Error cargando el modelo de Vensim.')) # Parámetros estéticos de ejecución. cmd_vensim(func=mod.vensim_be_quiet, args=[2], mensaje_error=_('Error en la comanda "vensim_be_quiet".'), val_error=-1) return mod
def test_interpol_no_necesaria(símismo): res = símismo.bd.interpolar('var_completo', fechas=('2000', '2002-1-1'), lugares='708') ref = símismo.bd.obt_vals('var_completo', lugares='708') xrt.assert_equal( res.where(res[_('fecha')].isin(pd.to_datetime(('2000', '2002-1-1'))), drop=True), ref.where(ref[_('fecha')].isin(pd.to_datetime(('2000', '2002-1-1'))), drop=True) )
def generar_mds(archivo, motor=None): """ Esta función genera una instancia de modelo de DS. Identifica el tipo_mod de fuente por su extensión (p. ej., .vpm) y después genera una instancia de la subclase apropiada de :class:`~tinamit.EnvolturasMDS.EnvolturasMDS`. Parameters ---------- archivo : str El fuente del modelo DS. motor : type | list[type] Las clases de envoltura MDS que quieres considerar para generar este modelo. Returns ------- EnvolturaMDS Un modelo DS. """ archivo = verificar_dirección_arch(archivo) # Identificar la extensión. ext = os.path.splitext(archivo)[1] # Verificar si podemos leer este tipo_mod de fuente. if ext not in dic_motores: # Mensaje para modelos todavía no incluidos en Tinamit. raise ValueError(_('El tipo_mod de modelo "{}" no se acepta como modelo DS en Tinamit al momento. Si piensas' 'que podrías contribuir aquí, ¡contáctenos!').format(ext)) else: errores = {} if motor is None: motores_potenciales = dic_motores[ext] else: if not isinstance(motor, list): motor = [motor] motores_potenciales = [x for x in dic_motores[ext] if x in motor] if not len(motores_potenciales): raise ValueError(_('No encontramos envoltura potencial para modelos de tipo "{}".').format(ext)) for env in motores_potenciales: # noinspection PyBroadException try: mod = env(archivo) # type: EnvolturaMDS if mod.instalado(): return mod else: errores[env.__name__] = 'Programa no instalado.' except Exception: errores[env.__name__] = traceback.format_exc() raise ValueError( _('\n\nEl modelo' '\n\t"{}"' '\nno se pudo leer. Intentamos las envolturas siguientes, pero no funcionaron:{}' ).format(archivo, ''.join(['\n\n\t{}: \n{}'.format(env, e) for env, e in errores.items()])) )
def crear_dll_vensim(archivo): # pragma: sin cobertura if sys.platform[:3] != 'win': raise OSError(_('Desafortunadamente, el dll de Vensim únicamente funciona en Windows.')) try: return ctypes.WinDLL(archivo) except OSError: raise OSError(_('Archivo "{}" erróneo para el DLL de Vensim DSS.').format(archivo))
def interpolar(símismo, fechas): eje_ant = símismo.vals[_('fecha')] nuevas_fechas = fechas.values[~np.isin(fechas.values, eje_ant.values)] vals = símismo.vals if nuevas_fechas.size: vals = vals.reindex(fecha=np.concatenate((eje_ant.values, nuevas_fechas))) vals = vals.sortby(_('fecha')) vals = vals.interpolate_na(_('fecha')) return vals.where(vals[_('fecha')].isin(fechas), drop=True)
def __init__(símismo, var, t): símismo.var = var símismo.t = t dims = símismo.var.dims matr = np.zeros((len(t), *dims)) símismo.vals = xr.DataArray( matr, coords={_('fecha'): símismo.t.eje()}, dims=[_('fecha'), *('x_' + str(i) for i in range(len(dims)))] )
def _a_matr_xr(val): if isinstance(val, xr.DataArray): return val else: if not isinstance(val, np.ndarray): val = np.array([val]) return xr.DataArray( val.reshape((1, *val.shape)), coords={_('fecha'): [0]}, dims=[_('fecha'), *('x_' + str(i) for i in range(len(val.shape)))])
def test_interpol_con_fecha_única(símismo): res = símismo.bd.interpolar(['var_incompleto', 'var_completo'], fechas='2001') # Verificar interpolaciones vals = res.where( np.logical_and(res[_('lugar')] == '7', res[_('fecha')] == np.datetime64('2001-01-01')), drop=True ) npt.assert_allclose(vals['var_completo'].values, 2.500684) npt.assert_allclose(vals['var_incompleto'].values, 23.3394, rtol=0.001)
def _obt_a_t(m_xr, t, interpol): m_xr = m_xr.unstack() t_rel = relativizar_eje(m_xr, t) if interpol and m_xr.sizes[_('fecha')] > 1: return m_xr.interp(**{_('fecha'): t_rel}).dropna(_('fecha')) try: return m_xr.reindex({_('fecha'): t_rel}).dropna(_('fecha')) except (KeyError, IndexError): return np.nan
def _estab_mod_extern(símismo, modelo): if isinstance(modelo, str): if not os.path.isfile(modelo): raise ValueError(_('El archivo "{}" no existe... :(').format(modelo)) if os.path.splitext(modelo)[1] != '.py': raise ValueError(_('El archivo "{}" no parece ser un archivo Python.').format(modelo)) dir_mod, nombre_mod = os.path.split(modelo) sys.path.append(dir_mod) módulo = importar_mod(os.path.splitext(nombre_mod)[0]) candidatos = inspect.getmembers(módulo, inspect.isclass) cands_final = {} for nmb, obj in candidatos: if callable(obj): try: obj = obj() except BaseException: continue if isinstance(obj, ModeloBF): cands_final[nmb] = obj if len(cands_final) == 0: raise AttributeError(_('El fuente especificado ("{}") no contiene subclase de "ModeloBF".') .format(modelo)) elif len(cands_final) == 1: símismo.modelo = cands_final[list(cands_final)[0]] else: try: símismo.modelo = cands_final['Envoltura'] except KeyError: elegido = list(cands_final)[0] símismo.modelo = elegido avisar(_('Había más que una instancia de "ModeloBF" en el fuente "{}", ' 'y ninguna se llamaba "Envoltura". Tomaremos "{}" como la envoltura ' 'y esperaremos que funcione. Si no te parece, asegúrate que la definición de clase u el' 'objeto correcto se llame "Envoltura".').format(modelo, elegido)) else: if callable(modelo): modelo = modelo() if isinstance(modelo, ModeloBF): símismo.modelo = modelo else: raise TypeError(_('El parámetro "modelo" debe ser o una instancia o subclase de "ModeloBF", o un ' 'fuente Python que contiene uno.')) # Crear el vínculo símismo.variables = símismo.modelo.variables símismo.vars_saliendo = símismo.modelo.vars_saliendo símismo.vars_clima = símismo.modelo.vars_clima símismo.archivo = símismo.modelo.archivo
def __init__(símismo, archivo, nombre='mds', dll_Vensim=None): """ La función de inicialización del modelo. Creamos el vínculo con el DLL de VENSIM y cargamos el modelo especificado. :param archivo: El fuente del modelo que quieres cargar en formato .vpm. :type archivo: str """ # Llamar el DLL de Vensim. if dll_Vensim is None: lugares_probables = [ 'C:\\Windows\\System32\\vendll32.dll', 'C:\\Windows\\SysWOW64\\vendll32.dll' ] arch_dll_Vensim = símismo._obt_val_config( llave='dll_Vensim', cond=os.path.isfile, respaldo=lugares_probables) if arch_dll_Vensim is None: símismo.dll = None else: símismo.dll = crear_dll_Vensim(arch_dll_Vensim) else: símismo.dll = crear_dll_Vensim(dll_Vensim) if símismo.dll is None: return # Inicializar Vensim cmd_vensim(func=símismo.dll.vensim_command, args=[''], mensaje_error=_('Error iniciando VENSIM.')) # Cargar el modelo cmd_vensim(func=símismo.dll.vensim_command, args='SPECIAL>LOADMODEL|%s' % archivo, mensaje_error=_('Error cargando el modelo de VENSIM.')) # Parámetros estéticos de ejecución. cmd_vensim(func=símismo.dll.vensim_be_quiet, args=[2], mensaje_error=_('Error en la comanda "vensim_be_quiet".'), val_error=-1) # El paso para incrementar símismo.paso = 1 # Una lista de variables editables símismo.editables = [] # Inicializar ModeloVENSIM como una EnvolturasMDS. super().__init__(archivo=archivo, nombre=nombre)
def cerrar_vensim(mod): # Necesario para guardar los últimos valores de los variables conectados. (Muy incómodo, yo sé.) estab_paso(mod, 1) # justo acaso cmd_vensim(func=mod.vensim_command, args="GAME>GAMEON", mensaje_error=_('Error terminando la simulación Vensim.')) # ¡Por fin! Llamar la comanda para terminar la simulación. cmd_vensim(func=mod.vensim_command, args="GAME>ENDGAME", mensaje_error=_('Error terminando la simulación Vensim.'))
def simular(símismo, t_final=None, t_inic=None, paso=1, nombre_corrida='Corrida Tinamït', vals_inic=None, vals_extern=None, bd=None, lugar_clima=None, clima=None, vars_interés=None, guardar=True): """ Simula el modelo :class:`~tinamit.Conectado.SuperConectado`. :param t_final: El tiempo final de la simulación. :type t_final: int :param paso: El paso (intervalo de intercambio de valores entre los dos submodelos). :type paso: int :param nombre_corrida: El nombre de la corrida. El valor automático es ``Corrida Tinamit``. :type nombre_corrida: str :param t_inic: La fecha inicial de la simulación. Necesaria para simulaciones con cambios climáticos. :type t_inic: ft.datetime | ft.date | int | str :param lugar_clima: El lugares de la simulación. :type lugar_clima: Lugar :param tcr: El escenario climático según el sistema de la IPCC (``2.6``, ``4.5``, ``6.0``, o ``8.5``). ``0`` da el clima histórico. :type tcr: str | float | int :param recalc_clima: Si quieres recalcular los datos climáticos, si ya existen. :type recalc_clima: bool :param clima: Si es una simulación de cambios climáticos o no. :type clima: bool """ vals_inic = símismo._frmt_dic_vars(vals_inic) # ¡No se puede simular con menos de un modelo! if len(símismo.modelos) < 1: raise ValueError(_('Hay que conectar submodelos antes de empezar una simulación.')) # Si no estamos seguro de la conversión de unidades de tiempo, decirlo aquí. if símismo.conv_tiempo_dudoso: l_unids = [m.unidad_tiempo() for m in símismo.modelos.values()] avisar(_('No se pudo inferir la conversión de unidades de tiempo entre {}.\n' 'Especificarla con la función .estab_conv_tiempo().\n' 'Por el momento pusimos el factor de conversión a 1, pero probablemente no es lo que quieres.') .format(', '.join(l_unids))) # Todo el restode la simulación se hace como en la clase pariente return super().simular( t_final=t_final, t_inic=t_inic, paso=paso, nombre_corrida=nombre_corrida, vals_inic=vals_inic, vals_extern=vals_extern, bd=bd, lugar_clima=lugar_clima, clima=clima, vars_interés=vars_interés, guardar=guardar )
def _verificar(símismo): v_f = símismo.var_fuente v_r = símismo.var_recip if v_f.dims != v_r.dims: raise ValueError( _('Dimensiones incompatibles entre variables "{}" {} y "{}" {}.' ).format(v_f, v_f.dims, v_r, v_r.dims)) if not _líms_compat(símismo.var_fuente.líms, símismo.var_recip.líms): avisar( _('Límites potencialmente incompatibles entre variables "{}" y "{}".' ).format(símismo.var_fuente, símismo.var_recip))
def comb_datos(símismo, vars_clima, combin, f_inic, f_final): """ Esta función combina datos climáticos entre dos fechas. :param vars_clima: Los variables de clima de interés. :type vars_clima: list[str] | str :param combin: Cómo hay que combinar (promedio o total) :type combin: list[str] | str :param f_inic: La fecha inicial :type f_inic: ft.datetime | ft.date :param f_final: La fecha final :type f_final: ft.datetime | ft.date :return: Un diccionario con los resultados. :rtype: dict[float] """ bd = símismo.اعداد_دن # type: pd.DataFrame datos_interés = bd.loc[f_inic:f_final] if isinstance(combin, str): combin = [combin] if isinstance(vars_clima, str): vars_clima = [vars_clima] resultados = {} for v, c in zip(vars_clima, combin): try: v_conv = conv_vars[v] except KeyError: raise ValueError( _('El variable "{}" está erróneo. Debe ser uno de:\n' '\t{}').format(v, ', '.join(conv_vars))) if c is None: if v in [ 'Temperatura máxima', 'Temperatura mínima', 'Temperatura promedia' ]: c = 'prom' else: c = 'total' if c == 'prom': resultados[v] = datos_interés[v_conv].mean() elif c == 'total': resultados[v] = datos_interés[v_conv].sum() else: raise ValueError( _('El método de combinación de datos debe ser "prom" o "total".' )) return resultados
def estab_conv_tiempo(símismo, mod_base, conv): """ Esta función establece la conversión de tiempo entre los modelos (útil para unidades que Tinamït no reconoce). :param mod_base: El modelo con la unidad de tiempo mayor. :type mod_base: str :param conv: El factor de conversión con la unidad de tiempo del otro modelo. Si hay más que 2 modelos conectados, *debe* ser un diccionario con los nombres de los modelos y sus factores de conversión. :type conv: int | dict[str, int] """ # Veryficar que el modelo de base es un nombre de modelo válido. if mod_base not in símismo.modelos: raise ValueError(_('El modelo "{}" no existe en este modelo conectado.').format(mod_base)) # Convertir `conv`, si necesario. if isinstance(conv, int): if len(símismo.modelos) == 2: # Si hay dos modelos conectados, convertir `conv` a un diccionario. otro = next(m for m in símismo.modelos if m != mod_base) conv = {otro: conv} else: raise TypeError(_('Debes especificar un diccionario de factores de conversión si tienes' 'más que 2 modelos conectados.')) else: # Asegurarse que todos los modelos en `conv` existen en `símismo.modelos`. m_error = [m for m in conv if m not in símismo.modelos] if len(m_error): raise ValueError(_('Los modelos siguientes no existen en el modelo conectado: {}') .format(', '.join(m_error))) # Assegurarse que todos los modelos en `símismo.modelos` existen en `conv`. if not all(m in símismo.modelos for m in conv if m != mod_base): raise ValueError(_('`Conv` debe incluir todos los modelos en este modelo conectado.')) # Establecer las conversiones símismo.conv_tiempo[mod_base] = 1 for m, c in conv.items(): símismo.conv_tiempo[m] = c # Y guardar el nombre del modelo de base. símismo.mod_base_tiempo = mod_base # Si había duda acerca de la conversión de tiempo, ya no hay. símismo.conv_tiempo_dudoso = False
def _obt_a_t(m_xr, t, interpol): m_xr = m_xr.unstack() t_rel = relativizar_eje(m_xr, t) # para hacer: arreglar de forma corecta if m_xr['fecha'].values[0] == 0: m_xr['fecha'] = [ t.f_inic if isinstance(t, TiempoCalendario) else t[0] ] return m_xr if interpol and m_xr.sizes[_('fecha')] > 1: return m_xr.interp(**{_('fecha'): t_rel}).dropna(_('fecha')) try: return m_xr.reindex({_('fecha'): t_rel}).dropna(_('fecha')) except (KeyError, IndexError): return np.nan
def _verificar_estado_vars(símismo): # Aquí tenemos que verificar el estado interno de SAHYSMOD porque éste, siendo SAHYSMOD, da mensajes de error # con el mínimo de información posible. a = símismo.variables['Area A - Seasonal fraction area crop A'].obt_vals_paso() b = símismo.variables['Area B - Seasonal fraction area crop B'].obt_vals_paso() fsa = símismo.variables['FsA - Water storage efficiency crop A'].obt_vals_paso() fsb = símismo.variables['FsB - Water storage efficiency crop B'].obt_vals_paso() if np.any(np.logical_and(fsa == -1, a > 0)): raise ValueError(_('Los valores de FsA no pueden faltar en polígonos que tienen superficie con cultivo A.')) if np.any(np.logical_and(fsb == -1, b > 0)): raise ValueError(_('Los valores de FsB no pueden faltar en polígonos que tienen superficie con cultivo B.'))
def avanzar_modelo(símismo, n_ciclos): arch_egreso = os.path.join(símismo.direc_trabajo, 'SAHYSMOD.out') arch_ingreso = os.path.join(símismo.direc_trabajo, 'SAHYSMOD.inp') símismo._escribir_archivo_ingr(n_ciclos=n_ciclos, archivo=arch_ingreso) # Limpiar archivos de egresos que podrían estar allí if os.path.isfile(arch_egreso): os.remove(arch_egreso) # Correr la comanda desde la línea de comanda comanda = '"{SAHYSMOD}" "{ingreso}" "{egreso}"'.format( SAHYSMOD=símismo.exe_SAHYSMOD, ingreso=arch_ingreso, egreso=arch_egreso) run(comanda, cwd=símismo.direc_trabajo) # Verificar que SAHYSMOD generó egresos. if not os.path.isfile(arch_egreso): with open(os.path.join(símismo.direc_trabajo, 'error.lst')) as d: mnsj_sahysmod = d.readlines() raise FileNotFoundError( _('\nEl modelo SAHYSMOD no generó egreso. Esto probablemente quiere decir que tuvo problema interno.' '\n¡Diviértete! :)' '\nMensajes de error de SAHYSMOD:' '\n{}').format(mnsj_sahysmod)) símismo.leer_egr_modelo(n_ciclos=n_ciclos)
def __init__(símismo, archivo, nombre='SAHYSMOD'): símismo.archivo = archivo símismo.direc_trabajo = '' # Directorio vacío para guardar datos de ingresos después símismo.dic_ingr = {} # Buscar la ubicación del modelo SAHYSMOD. símismo.exe_SAHYSMOD = símismo.obt_conf( 'exe', cond=os.path.isfile, mnsj_err= _('Debes especificar la ubicación del ejecutable SAHYSMOD, p. ej.' '\n\tModeloSAHYSMOD.estab_conf("exe", "C:\\Camino\\hacia\\mi\\SAHYSMODConsole.exe")' '\npara poder hacer simulaciones con modelos SAHYSMOD.')) # Leer el fuente de ingreso símismo.dic_ingr = leer_info_dic_paráms(archivo_fnt=símismo.archivo) variables = VariablesSAHYSMOD(inic=símismo.dic_ingr) # Inicializar la clase pariente. super().__init__(variables=variables, nombre=nombre) # Establecer los variables climáticos. símismo.conectar_var_clima(var='Pp - Rainfall', var_clima='بارش', combin='total', conv=0.001)
def __init__(símismo, archivo, nombre='mds'): nmbr, ext = os.path.splitext(archivo) if ext == '.mdl': símismo.tipo = '.mdl' # Únicamente recrear el archivo .py si necesario if os.path.isfile(nmbr + '.py') and (os.path.getmtime(nmbr + '.py') > os.path.getmtime(archivo)): símismo.modelo = pysd.load(nmbr + '.py') else: símismo.modelo = pysd.read_vensim(archivo) elif ext in ['.xmile', '.xml']: símismo.tipo = '.xmile' símismo.modelo = pysd.read_xmile(archivo) elif ext == '.py': # Modelos PySD ya traducidos símismo.tipo = '.py' símismo.modelo = pysd.load(archivo) else: raise ValueError( _('PySD no sabe leer modelos del formato "{}". Debes darle un modelo ".mdl" o ".xmile".' ).format(ext)) símismo._conv_nombres = {} símismo.tiempo_final = None símismo.cont_simul = False símismo.paso_act = 0 símismo.vars_para_cambiar = {} símismo._res_recién = None # pd.DataFrame super().__init__(archivo, nombre=nombre)
def gen_extern(datos, interpol=True): """ Transforma datos en objeto :class:`~tinamit.extern.Extern`. Parameters ---------- datos: Extern or pd.DataFrame or xr.Dataset or dict Los datos. interpol: bool Si se pueden interpolar los datos. Returns ------- Extern """ if isinstance(datos, Extern) or datos is None: return datos if isinstance(datos, pd.DataFrame): datos = datos.to_xarray().rename({'index': _('fecha')}) if isinstance(datos, xr.Dataset): return Extern({vr: datos[vr] for vr in datos.data_vars}, interpol) elif isinstance(datos, dict): return Extern({vr: _a_matr_xr(vl) for vr, vl in datos.items()}) raise TypeError(type(datos))
def verificar_dirección_arch(archivo): """ Verificar que existe un archivo, y devuelve la dirrección absoluta. Muy útil para importaciones relativas. Parameters ---------- archivo : str El archivo para verificar. Returns ------- str La dirrección absoluta del archivo. Raises ------ FileNotFoundError Si el archivo no existe. """ dir_completa = os.path.abspath(archivo) if not os.path.isfile(dir_completa): from tinamit.config import _ raise FileNotFoundError( _('No se encuentra el archivo "{}"').format( os.path.abspath(archivo))) return dir_completa
def _obt_dll_vensim(): if sys.platform[:3] != 'win': raise OSError( _('\nDesafortunadamente, el DLL de Vensim funciona únicamente en Windows.' '\nPuedes intentar la envoltura ModeloPySDMDL con un modelo .mdl en vez.' )) return ctypes.WinDLL(_obt_arch_dll_vensim())