示例#1
0
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.'))
示例#2
0
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
示例#3
0
    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
示例#4
0
    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
示例#5
0
    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.'))
示例#6
0
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
示例#7
0
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
示例#8
0
    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)
        )
示例#9
0
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()]))
        )
示例#10
0
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))
示例#11
0
 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)
示例#12
0
    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)))]
        )
示例#13
0
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)))])
示例#14
0
    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)
示例#15
0
    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
示例#16
0
    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
示例#17
0
    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)
示例#18
0
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.'))
示例#19
0
    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
        )
示例#20
0
    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))
示例#21
0
    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
示例#22
0
    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
示例#23
0
 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
示例#24
0
    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.'))
示例#25
0
    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)
示例#26
0
    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)
示例#27
0
    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)
示例#28
0
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))
示例#29
0
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
示例#30
0
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())