Skip to content

Commit

Permalink
Merge pull request #3 from julienmalard/spotpy
Browse files Browse the repository at this point in the history
Cambiar PyMC2 por SpotPy
  • Loading branch information
julienmalard authored Oct 23, 2018
2 parents 34461e1 + d649f9e commit c5d04e0
Show file tree
Hide file tree
Showing 81 changed files with 839 additions and 2,234 deletions.
File renamed without changes.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
long_description='Tiko\'n es una herramienta para desarrollar modelos de agroecología (relaciones tróficas'
'entre insectos, enfermedades, y plantas). Está escrito para permitir la integración de modelos'
'de cultivos existentes.',
install_requires=['pymc', 'numpy', 'matplotlib', 'scipy', 'SALib', 'pathvalidate', 'pymc3', 'theano'],
install_requires=['numpy', 'matplotlib', 'scipy', 'SALib', 'pathvalidate', 'pymc3', 'theano', 'spotpy'],
classifiers=[
'License :: OSI Approved :: GNU General Public License v3 (GPLv3)',
'Programming Language :: Python :: 3 :: Only',
Expand Down
2 changes: 1 addition & 1 deletion tikon/Controles.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import pathvalidate
from pkg_resources import resource_filename

usar_pymc3 = False

# Este documento contiene información general para el programa Tiko'n

Expand Down Expand Up @@ -39,6 +38,7 @@ def espec_dir_modelo_cult(modelo, directorio):
def valid_archivo(archivo):
direc, nombre = os.path.split(archivo)
disco, direc = os.path.splitdrive(direc)
return os.path.join(disco, direc, nombre)

direc = pathvalidate.sanitize_file_path(direc, replacement_text='_')
nombre = pathvalidate.sanitize_filename(nombre, replacement_text='_')
Expand Down
67 changes: 22 additions & 45 deletions tikon/Coso.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@

import numpy as np

from tikon.Matemáticas.Variables import VarSciPy, VarCalib
from tikon import __correo__
from tikon.Controles import directorio_base, dir_proyectos
from tikon.Matemáticas import Arte, Incert
from tikon.Matemáticas.Calib import ModBayes, ModGLUE, ModCalib
from tikon.Matemáticas.Calib import ModSpotPy, ModCalib
from tikon.Matemáticas.Experimentos import Experimento
from tikon.Matemáticas.Sensib import prep_anal_sensib
from tikon.Matemáticas.Variables import VarSciPy, VarSpotPy


class Coso(object):
Expand Down Expand Up @@ -790,7 +790,7 @@ def simular(símismo, exper=None, nombre=None, paso=1, tiempo_final=None, n_rep_
símismo.dibujar(exper=exper, directorio=directorio_dib, mostrar=mostrar, **opciones_dib)

def calibrar(símismo, nombre=None, aprioris=None, exper=None, paso=1, n_rep_estoc=10, tiempo_final=None,
n_iter=10000, quema=100, extraer=10, método='Metrópolis adaptivo', pedazitos=None,
n_iter=10000, quema=100, extraer=10, método='mle', pedazitos=None,
usar_especificadas=True, dibujar=False, depurar=False):
"""
Esta función calibra un Simulable. Para calibrar un modelo, hay algunas cosas que hacer:
Expand Down Expand Up @@ -898,23 +898,18 @@ def calibrar(símismo, nombre=None, aprioris=None, exper=None, paso=1, n_rep_est
# 5. Conectar a las observaciones
d_obs = símismo.dic_simul['d_obs_calib'] # type: dict[dict[np.ndarray]]

# 6. Creamos el modelo ModCalib de calibración, lo cual genera variables PyMC
if método.lower() == 'metrópolis' or método.lower() == 'metrópolis adaptivo':
símismo.ModCalib = ModBayes(función=símismo._simul_exps,
dic_argums=dic_argums,
d_obs=d_obs,
lista_d_paráms=lista_paráms,
aprioris=lista_aprioris,
lista_líms=lista_líms,
id_calib=nombre,
función_llenar_coefs=símismo._llenar_coefs,
método=método
)
elif método.lower() == 'glue':
símismo.ModCalib = ModGLUE()

else:
raise ValueError
# 6. Creamos el modelo ModCalib de calibración, lo cual genera variables SpotPy
símismo.ModCalib = ModSpotPy(
función=símismo._simul_exps,
dic_argums=dic_argums,
d_obs=d_obs,
lista_d_paráms=lista_paráms,
aprioris=lista_aprioris,
lista_líms=lista_líms,
id_calib=nombre,
función_llenar_coefs=símismo._llenar_coefs,
método=método
)

if nombre_pdzt_ant is not None:
símismo.borrar_calib(id_calib=nombre_pdzt_ant)
Expand Down Expand Up @@ -1054,9 +1049,6 @@ def validar(símismo, exper, nombre=None, calibs=None, paso=1, n_rep_parám=20,
:param dib_dists: Si hay que dibujar las distribuciones utilizadas para la simulación.
:type dib_dists: bool
:param dib_dists: Si hay que dibujar las distribuciones utilizadas para la simulación.
:type dib_dists: bool
:return: Un diccionario con los resultados de la validación.
:rtype: dict
"""
Expand Down Expand Up @@ -1529,15 +1521,15 @@ def _prep_dic_simul(símismo, exper, n_rep_estoc, n_rep_paráms, paso, n_pasos,
n_rep_estoc=n_rep_estoc, n_rep_parám=n_rep_paráms)

if tipo == 'calib':
símismo._gen_dics_calib(exper=exper)
símismo._gen_dics_calib(exper=exper, n_rep_estoc=n_rep_estoc)

def _gen_dic_predics_exps(símismo, exper, n_rep_estoc, n_rep_parám, paso, n_pasos, detalles):
raise NotImplementedError

def _gen_dics_valid(símismo, exper, paso, n_pasos, n_rep_estoc, n_rep_parám):
raise NotImplementedError

def _gen_dics_calib(símismo, exper):
def _gen_dics_calib(símismo, exper, n_rep_estoc):
raise NotImplementedError

def _simul_exps(símismo, paso, n_pasos, extrn, detalles, devolver_calib, depurar=False):
Expand Down Expand Up @@ -1580,23 +1572,15 @@ def _simul_exps(símismo, paso, n_pasos, extrn, detalles, devolver_calib, depura
print('Simulación (%s) calculada en: ' % exp, time.time() - antes)

# Procesar los egresos de la simulación.
antes = time.time()
símismo._procesar_simul()
dif_p_s = time.time() - antes

if devolver_calib:
# Convertir los diccionarios de predicciones en un vector numpy.
antes = time.time()
símismo._procesar_valid()
dif_p_v = time.time() - antes
antes = time.time()
símismo._procesar_calib()
dif_p_c = time.time() - antes
print('Procesando predicciones: \n\tSimul: {}\n\tValid: {}\n\tCalib: {}\n\tTotal: {}'
.format(dif_p_s, dif_p_v, dif_p_c, dif_p_s + dif_p_v + dif_p_c))

# Devolver las predicciones.
return símismo.dic_simul['d_calib']
return símismo.dic_simul

def _procesar_simul(símismo):
"""
Expand Down Expand Up @@ -1658,22 +1642,15 @@ def _procesar_calib(símismo):
for t_dist, l_matr_v in d_l_m_valid.items():
d_dist = d_calib[t_dist] # type: dict

# Por una razón extraña, PyMC se queja si no hacemos copias aquí. A ver si hay que hacer lo mismo con PyMC3.
d_dist['mu'] = np.zeros_like(d_dist['mu'])
d_dist['sigma'] = np.zeros_like(d_dist['sigma'])

for i, m in enumerate(l_matr_v):
r = d_índs[t_dist][i]['rango']
parc, etps, días = d_índs[t_dist][i]['índs']

if t_dist == 'Normal':
d_dist['mu'][r[0]:r[1]] = np.mean(m[parc, :, 0, etps, días], axis=1)

# Evitar sigmas de 0. Causan muchos problemas después.
d_dist['sigma'][r[0]:r[1]] = np.maximum(1, np.std(m[parc, :, 0, etps, días], axis=1))
d_dist[r[0]:r[1]] = m[parc, :, 0, etps, días]

else:
raise ValueError
raise ValueError(t_dist)

def _procesar_matrs_sens(símismo):
"""
Expand Down Expand Up @@ -1886,7 +1863,7 @@ def sacar_dists_de_dic(d, l=None, u=None):
u.append(ll)
sacar_dists_de_dic(d=v, l=l, u=u)

elif isinstance(v, VarCalib):
elif isinstance(v, VarSpotPy):
u.append(ll)
l.append((u.copy(), v))
u.pop()
Expand Down Expand Up @@ -2096,7 +2073,7 @@ def prep_receta_json(d, d_egr=None):
# Transformar matrices numpy a texto
d_egr[ll] = v.tolist()

elif isinstance(v, VarCalib):
elif isinstance(v, VarSpotPy):

# Si el itema es un variable de PyMC, borrarlo
d_egr.pop(ll)
Expand Down
6 changes: 3 additions & 3 deletions tikon/Matemáticas/Arte.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from matplotlib.backends.backend_agg import FigureCanvasAgg as TelaFigura
from matplotlib.figure import Figure as Figura

from tikon.Matemáticas.Variables import VarSciPy, VarCalib
from tikon.Matemáticas.Variables import VarSciPy, VarSpotPy
from tikon.Controles import valid_archivo


Expand Down Expand Up @@ -265,7 +265,7 @@ def graficar_dists(dists, valores=None, rango=None, título=None, archivo=None):
# Poner cada distribución en el gráfico
for dist in dists:

if isinstance(dist, VarCalib):
if isinstance(dist, VarSpotPy):
ejes = fig.subplots(1, 2)

dist.dibujar(ejes=ejes)
Expand Down Expand Up @@ -300,7 +300,7 @@ def graficar_dists(dists, valores=None, rango=None, título=None, archivo=None):
# Si hay valores, hacer un histrograma
if valores is not None:
valores = valores.astype(float)
ejes.hist(valores, normed=True, color='green', histtype='stepfilled', alpha=0.2)
ejes.hist(valores, density=True, color='green', histtype='stepfilled', alpha=0.2)

# Si se especificó un título, ponerlo
if título is not None:
Expand Down
Loading

0 comments on commit c5d04e0

Please sign in to comment.