# -*- coding: utf-8 -*-
"""
Created on Fri Apr 20 13:49:49 2018
@author: A.Goumilevski
"""
import sys, os
path = os.path.dirname(os.path.abspath(__file__))
working_dir = os.path.abspath(os.path.join(path,"../../.."))
if os.path.exists(working_dir):
sys.path.append(working_dir)
import re
import datetime as dt
import tkinter as tk
from tkinter import filedialog as fd
from tkinter import messagebox
from tkinter import ttk
#from tkinter import W,N,E,S,BOTH
import numpy as np
from snowdrop.src.utils.util import getNamesAndValues
#from snowdrop.src.utils.interface import *
minWidth = 1400
minHeight = 650
maxWidth = 1600
maxHeight = 800
strDescription = "Description:"
strEqs = "Equations:"
strSession = "Session"
strInput = "Input"
strParams = "Parameters:"
strParamsRange = "Parameters Range:"
strEndogVarInitValues = "Endogenous Variables Starting Values:"
strExogVariables = "Exogenous Variables Values:"
strShocks = "Shocks:"
strTimeRange = "Time Range:"
strFreq = "Frequency:"
strFreqList = ['Annually','Quarterly','Monthly','Weekly','Daily']
strSteadyStates = "Find Steady-State Solution for Parameters Range:"
strSteadyStateSolution = "Steady-State Solution:"
strSimulationResults = "Simulation Results:"
showSessionTab = False
[docs]
class Application(tk.Frame):
def __init__(self, master=None,file_path=None):
self.containers = {}
self.master = master
tk.Frame.__init__(self, master)
if file_path is None:
txtDescr="";txtEqs="";txtParams="";txtParamsRange="";txtEndogVars="";txtExogVars="";txtShocks="";txtRange="";txtFreq="";eqLabels=""
else:
txtDescr,txtEqs,txtParams,txtParamsRange,txtEndogVars,txtExogVars,txtShocks,varLabels,txtRange,txtFreq,eqLabels,comments = readFile(file_path)
self.description = txtDescr
self.createWidgets(txtDescr,txtEqs,txtParams,txtParamsRange,txtEndogVars,txtExogVars,txtShocks,txtRange,txtFreq)
self.tabContainer = None
self.tableContainer = None
self.eqLabels = eqLabels
self.input_file = None
self.temp_file = None
self.history_file = None
self.comments = None
self.labels = []
self.pack()
[docs]
def OpenFile(self):
""" Open file dialog."""
#fdir = os.path.abspath(os.path.join(working_dir,"../models/Sirius"))
fdir = os.path.abspath(os.path.join(working_dir,"../../supplements/models/TOY/RBC.yaml"))
file_path = fd.askopenfilename(initialdir=fdir)
self.input_file = os.path.abspath(file_path)
for key in self.containers.keys():
tab= self.containers[key]
tab.destroy()
txtDescr,txtEqs,txtParams,txtParamsRange,txtEndogVars,txtExogVars,txtShocks,varLabels,txtRange,txtFreq,eqLabels,comments = readFile(file_path)
self.description = txtDescr
self.labels= varLabels
self.createWidgets(txtDescr,txtEqs,txtParams,txtParamsRange,txtEndogVars,txtExogVars,txtShocks,txtRange,txtFreq)
self.comments = comments
if "tab2" in self.containers:
tab = self.containers["tab2"]
self.notebook.select(tab)
[docs]
def OpenHistoryFile(self):
"""Open history file dialog."""
file_path = fd.askopenfilename()
self.history_file = file_path
[docs]
def RestoreSession(self):
"""Read session file."""
path = os.path.dirname(os.path.abspath(__file__))
file_path = os.path.abspath(os.path.join(path,'../../data/session.txt'))
obj = self.containers[strInput]
obj.delete('1.0', tk.END)
with open(file_path, 'r') as f:
for line in f:
ln = line.strip() + "\n"
obj.insert(tk.END,ln)
[docs]
def Save(self):
"""Save GUI data into temp.yaml file."""
if checkNumberOfEquationsAndVariables(self):
SaveYamlOutput(self)
[docs]
def SaveTemplate(self):
"""Save GUI data into template.yaml file."""
if checkNumberOfEquationsAndVariables(self):
SaveTemplateOutput(self)
[docs]
def SaveSession(self):
"""Save user input to a text file."""
path = os.path.dirname(os.path.abspath(__file__))
file_path = os.path.abspath(os.path.join(path, '../../data/session.txt'))
obj = self.containers[strInput]
session = obj.get("1.0",tk.END)
with open(file_path, 'w') as f:
for line in session.split("\n"):
f.write(line + "\n")
[docs]
def FindSteadyState(self):
"""
Finds the steady state solution
"""
from snowdrop.src.driver import importModel
from snowdrop.src.driver import findSteadyStateSolution
from snowdrop.src.driver import findSteadyStateSolutions
# Save GUI data to template file
self.Save()
figs = None
# Run simulations
# Create model
model = importModel(self.temp_file)
# Get variables names
variables = model.symbols['variables']
parameters = model.symbols['parameters']
order = np.argsort(variables)
param_range = getParamRange(self)
par_range = {}; data = []
for p in param_range:
p = p.replace("="," : ")
if ':' in p:
left,right = p.split(':')
left = left.strip()
right = right.replace(' ','')
if left in parameters:
if '-' in right:
tmp = right.split('-')
tmp = list(filter(None,tmp))
if len(tmp) == 2:
par_range[left] = [float(tmp[0]),float(tmp[1])]
if len(par_range) > 0:
arr_ss,par_ss,par_names,mp = findSteadyStateSolutions(model=model,par_range=par_range,number_of_steps=10,Plot=False,Output=False)
sort = False
for i,k in enumerate(mp):
arr = mp[k]
for x in arr:
data.append(['',''])
x0 = np.around(x[0], decimals=3)
data.append([k,x0])
z = np.around(x[1], decimals=3)
m = dict(zip(variables,z))
for i in order:
v = variables[i]
if "_plus_" in v or "_minus_" in v:
continue
data.append([v,m[v]])
data = np.array(data)
#import matplotlib
#matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from snowdrop.src.graphs.util import plotSteadyState
figures_dir = os.path.abspath(os.path.join(working_dir,'graphs'))
figs = plotSteadyState(path_to_dir=figures_dir,variables=variables,arr_ss=arr_ss,par_ss=par_ss,sizes=(3,2),save=False)
# Remove figures tabs
self.removeFigures()
# Place figures in new tabs
for i,fig in enumerate(figs):
tabControl = self.notebook
tab = ttk.Frame(tabControl)
tabName = 'Steady State Figure #' + str(1+i)
self.containers[tabName] = tab
tabControl.add(tab,text=tabName)
canvas = FigureCanvasTkAgg(fig, master=tab)
canvas.get_tk_widget().pack(padx=100,pady=100,side=tk.TOP,fill=tk.BOTH,expand=tk.TRUE)
canvas.draw()
else:
data = findSteadyStateSolution(model=model,Output=False)
data = np.around(data, decimals=3)
arr1 = []; arr2 = []; sort = True
for i in order:
v = variables[i]
if "_plus_" in v or "_minus_" in v:
continue
arr1.append(v)
arr2.append(data[0][i] if data[0][i] != 0 else data[1][i])
data = np.column_stack((arr1,arr2))
tab = self.containers["tab4"]
if not self.tabContainer is None:
self.tabContainer.destroy()
# Populate widgets of this tab
container = tk.Frame(tab)
self.cl = tk.Button(container, fg = "black", bg = "white")
self.cl["text"] = "CLOSE"
self.cl["command"] = self.Close
self.cl.pack(side=tk.RIGHT,padx=5,pady=5)
self.cl = tk.Button(container, fg = "black", bg = "white")
self.cl["text"] = "CLEAN"
self.cl["command"] = self.CleanResults
self.cl.pack(side=tk.RIGHT,padx=5,pady=5)
if not self.tableContainer is None:
self.tableContainer.destroy()
self.tableContainer = createTableWidget(tab,container,strSteadyStateSolution,columns=['Name','Value'],values=data,minheight=45,width=200,minwidth=50,anchor="w",stretch=True,side=tk.TOP,adjust_heading_to_content=True,sort=sort)
container.pack(side=tk.BOTTOM,fill=tk.BOTH,expand=True)
self.tabContainer = container
self.notebook.select(tab)
[docs]
def GetImpulseResponseFunctions(self):
"""Find and plot impulse response functions."""
from snowdrop.src.driver import getImpulseResponseFunctions
from snowdrop.src.graphs.util import plot
# Save GUI data to template file
self.Save()
# Remove figure tabs
self.removeFigures()
path = os.path.dirname(os.path.abspath(__file__))
path_to_dir = os.path.abspath(os.path.join(path,'../../../graphs'))
fname = self.temp_file
# Run simulations
data,rng = getImpulseResponseFunctions(fname=fname,Plot=False,Output=False)
columns,_ = getVariableNamesAndInitialValues(self)
# Get figures
figs = plot(path_to_dir=path_to_dir,data=[data],variable_names=columns,var_labels=self.labels,sizes=(2,2),figsize=(12,8),rng=rng,show=False,save=False)
# Output data
data = np.around(data, decimals=3)
if len(rng) > 0:
columns = ['Date'] + columns
dates = []
for d in rng:
dates.append(dt.datetime.strftime(d,'%m/%d/%Y'))
n = min(len(dates),len(data))
data = np.column_stack( (dates[:n],data[:n]) )
arr1 = []; arr2 = []
for i,v in enumerate(columns):
if "_plus_" in v or "_minus_" in v:
continue
arr1.append(v)
arr2.append(data[:,i])
columns = arr1
data = np.array(arr2).T
tab = self.containers["tab3"]
if not self.tabContainer is None:
self.tabContainer.destroy()
# Pupulate widgets of this tab
container = tk.Frame(tab)
self.cl = tk.Button(container, fg = "black", bg = "white")
self.cl["text"] = "CLOSE",
self.cl["command"] = self.Close
self.cl.pack(side=tk.RIGHT,padx=5,pady=5)
self.cl = tk.Button(container, fg = "black", bg = "white")
self.cl["text"] = "CLEAN",
self.cl["command"] = self.CleanResults
self.cl.pack(side=tk.RIGHT,padx=5,pady=5)
if not self.tableContainer is None:
self.tableContainer.destroy()
self.tableContainer = createTableWidget(tab,container,strSimulationResults,columns=columns,values=data,minheight=45,width=200,minwidth=50,side=tk.TOP,adjust_heading_to_content=True)
container.pack(side=tk.BOTTOM,fill=tk.BOTH,expand=True)
self.tabContainer = container
container = tk.Frame(tab)
self.notebook.select(tab)
#import matplotlib
#matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
# Place figures in new tabs
for i,fig in enumerate(figs):
tabControl = self.notebook
tab = ttk.Frame(tabControl)
tabName = 'Figure #' + str(1+i)
self.containers[tabName] = tab
tabControl.add(tab,text=tabName)
canvas = FigureCanvasTkAgg(fig, master=tab)
canvas.get_tk_widget().pack(padx=100,pady=100,side=tk.TOP,fill=tk.BOTH,expand=tk.TRUE)
canvas.draw()
tab = self.containers["tab2"]
self.notebook.select(tab)
[docs]
def Run(self):
"""Run simulations."""
from snowdrop.src.driver import run,importModel
from snowdrop.src.graphs.util import plot,plotDecomposition
# Save GUI data to template file
self.Save()
# Remove figure tabs
self.removeFigures()
path = os.path.dirname(os.path.abspath(__file__))
path_to_dir = os.path.abspath(os.path.join(path,'../../../graphs'))
fname = self.temp_file
# Run simulations
model = importModel(fname=fname)
data, rng = run(model=model,Plot=False,Output=False)
columns = model.symbols["variables"]
# Get periods
periods = []
shocks = getShocks(self)
for sh in shocks:
if 'Date' in sh:
d = sh.split("=")[1].strip()
date = dt.datetime.strptime(d,'%m/%d/%Y')
for i,d in enumerate(rng):
if d == date:
periods.append(i)
figs1 = plot(path_to_dir=path_to_dir,data=[data],variable_names=columns,var_labels=self.labels,sizes=(2,2),figsize=(12,8),rng=rng,show=False,save=False)
#decomp = ['dot4_cpi','dot4_cpi_x','dot4_gdp','lgdp_gap','lx_gdp_gap','mci','rmc','rr','rr_gap']
decomp = columns # All variables
figs2 = plotDecomposition(path_to_dir=path_to_dir,model=model,y=data,variables_names=columns,decomp_variables=decomp,periods=periods,rng=rng,sizes=(2,2),figsize=(12,8),show=False,save=False)
figs = figs1 + figs2
indices = sorted(range(len(columns)), key=lambda k: columns[k])
variable_names = [columns[i] for i in indices if not "_plus_" in columns[i] and not "_minus_" in columns[i]]
indices = [i for i,x in enumerate(columns) if x in variable_names]
# Output data
data = np.around(data, decimals=3)
data = data[:,indices]
if len(rng) > 0:
columns = ['Date'] + variable_names
dates = []
for d in rng:
dates.append(dt.datetime.strftime(d,'%m/%d/%Y'))
n = min(len(dates),len(data))
data = np.column_stack( (dates[:n],data[:n]) )
arr1 = []; arr2 = []
for i,v in enumerate(columns):
if "_plus_" in v or "_minus_" in v:
continue
arr1.append(v)
arr2.append(data[:,i])
columns = arr1
data = np.array(arr2).T
tab = self.containers["tab3"]
if not self.tabContainer is None:
self.tabContainer.destroy()
# Pupulate widgets of this tab
container = tk.Frame(tab)
self.cl = tk.Button(container, fg = "black", bg = "white")
self.cl["text"] = "CLOSE",
self.cl["command"] = self.Close
self.cl.pack(side=tk.RIGHT,padx=5,pady=5)
self.cl = tk.Button(container, fg = "black", bg = "white")
self.cl["text"] = "CLEAN",
self.cl["command"] = self.CleanResults
self.cl.pack(side=tk.RIGHT,padx=5,pady=5)
if not self.tableContainer is None:
self.tableContainer.destroy()
self.tableContainer = createTableWidget(tab,container,strSimulationResults,columns=columns,values=data,minheight=45,width=200,minwidth=50,side=tk.TOP,adjust_heading_to_content=True)
container.pack(side=tk.BOTTOM,fill=tk.BOTH,expand=True)
self.tabContainer = container
container = tk.Frame(tab)
self.notebook.select(tab)
# Place figures in new tabs
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
for i,fig in enumerate(figs):
tabControl = self.notebook
tab = ttk.Frame(tabControl)
tabName = 'Figure #' + str(1+i)
self.containers[tabName] = tab
tabControl.add(tab,text=tabName)
canvas = FigureCanvasTkAgg(fig, master=tab)
canvas.get_tk_widget().pack(padx=100,pady=100,side=tk.TOP,fill=tk.BOTH,expand=tk.TRUE)
canvas.draw()
[docs]
def Clean(self):
"""
Cleans session and command text boxes
"""
obj = self.containers[strInput]
obj.delete('1.0', tk.END)
obj = self.containers[strSession]
obj.config(state=tk.NORMAL)
obj.delete('1.0', tk.END)
obj.config(state=tk.DISABLED)
self.removeFigures()
[docs]
def CleanResults(self):
"""Clean content of tab #3."""
if not self.tabContainer is None:
self.tabContainer.destroy()
if not self.tableContainer is None:
self.tableContainer.destroy()
self.removeFigures()
tab = self.containers["tab2"]
self.notebook.select(tab)
[docs]
def ProcessCommands(self):
"""Run commands that user enetered in the Input text box."""
from io import StringIO
# create file-like string to capture output
old_stdout = sys.stdout
sys.stdout = StringIO()
my_stdout = sys.stdout
ansi_escape = re.compile(r'\x1B\[[0-?]*[ -/]*[@-~]')
obj = self.containers[strInput]
inp = obj.get("1.0",tk.END)
buf = []
for line in inp.split("\n"):
cmd = line.replace("\n","").strip()
if cmd:
try:
buf.append(">> " + cmd)
exec(cmd)
value = my_stdout.getvalue()
# Remove non-ansi characters
value = ansi_escape.sub('', value)
buf.append(value)
my_stdout.truncate(0)
except NameError as err:
buf.append("Name error: {0}".format(err) + "\n")
except SyntaxError as err:
buf.append("Syntax error: {0}".format(err) + "\n")
except OSError as err:
buf.append("OS error: {0}".format(err) + "\n")
except ValueError as err:
buf.append("Value error: {0}".format(err) + "\n")
except:
buf.append("Error: {0}".format(sys.exc_info()[0]) + "\n")
sys.stdout = old_stdout
# Populate session text box
obj = self.containers[strSession]
obj.config(state=tk.NORMAL)
obj.delete('1.0', tk.END)
obj.insert(tk.END,"\n".join(buf))
obj.config(state=tk.DISABLED)
[docs]
def Close(self):
"""Close the GUI."""
global root
root.destroy()
root.quit()
root = None
[docs]
def CloseFrame(self):
"""Close the frame."""
self.root.destroy()
self.root = None
[docs]
def Reset(self):
"""Reset the GUI."""
self.destroy()
app = Application(root)
app.master.title("Equations Editor")
app.master.minsize(minWidth, minHeight)
app.master.maxsize(maxWidth, maxHeight)
tab = self.containers["tab2"]
self.notebook.select(tab)
[docs]
def getEquationLabels(self):
"""Return equation labels and definition for Troll models."""
eqs = ""
if not self.eqLabels is None:
for lb, eq in self.eqLabels.iteritems():
eqs = eqs + lb + " : " + eq + "\n"
return eqs
[docs]
def getEquation(self,label):
"""
Returns equation definition by label for Troll models
"""
eq = ""
if not self.eqLabels is None and label in self.eqLabels.keys():
eq = self.eqLabels[label]
return eq
### End of class
[docs]
def createLabel(container,label,side=tk.TOP):
"""
Creates label widget
"""
container.eqsLabel = tk.Label(container)
container.eqsLabel["text"] = label
container.eqsLabel.pack(side=side)
[docs]
def createTextBoxWidget(self,parent,label,text,width,height,scrollBar=False,scroll="y",disabled=False,side=tk.TOP,background="white",foreground="black",selectbackground="black",inactiveselectbackground="white"):
"""
Creates text box widget
"""
container = tk.Frame(parent)
createLabel(container,label,side=tk.TOP)
if scrollBar:
container.sbTb = tk.Scrollbar(container,orient="vertical")
container.sbTb.pack({"side": "right","fill":"y"})
if scroll == "both":
container.sbTb2 = tk.Scrollbar(container,orient="horizontal")
container.sbTb2.pack({"side": "bottom","fill":"x"})
container.tb = tk.Text(container,width=width,height=height,background=background,foreground=foreground,selectbackground=selectbackground,inactiveselectbackground=inactiveselectbackground)
for i in range(len(text)):
container.tb.insert(tk.END,text[i].strip('\t'))
container.tb.pack(side=tk.TOP,fill=tk.BOTH,expand=tk.TRUE,padx=10,pady=10)
if scrollBar:
container.tb.configure(yscrollcommand=container.sbTb.set)
container.sbTb.config(command=container.tb.yview)
if scroll == "both":
container.tb.configure(xscrollcommand=container.sbTb2.set)
container.sbTb2.config(command=container.tb.xview)
if disabled:
container.tb.config(state=tk.DISABLED)
container.pack(side=side,fill=tk.BOTH,expand=tk.TRUE)
self.containers[label] = container.tb
return container.tb
[docs]
def readFile(file_path):
"""
Reads data file
"""
from snowdrop.src.utils.getDynareData import readDynareModelFile
from snowdrop.src.utils.getIrisData import readIrisModelFile
from snowdrop.src.utils.getTemplateData import readTemplateFile
from snowdrop.src.utils.getTrollData import readTrollModelFile
from snowdrop.src.utils.getXmlData import readXmlModelFile
from snowdrop.src.utils.getYamlData import readYamlModelFile
eqLabels = None; labels=None; comments = None
fname, ext = os.path.splitext(file_path)
name,_ = os.path.splitext(os.path.basename(file_path))
if ext.lower() in [".inp",".src"]:
txtEqs,txtParams,txtParamsRange,txtEndogVars,txtExogVars,txtShocks,txtRange,txtFreq,varLabels,eqLabels,modelName,comments,undefined_parameters = readTrollModelFile(file_path)
if modelName:
txtDescr = modelName
else:
txtDescr = 'Troll Model ' + name
if len(undefined_parameters):
messagebox.showwarning("Warning",f"{len(undefined_parameters)} parameters were not defined and were set to one.")
elif ext.lower() == ".mod":
txtEqs,txtParams,txtParamsRange,txtEndogVars,txtExogVars,txtShocks,txtRange,txtFreq,description = readDynareModelFile(file_path)
if description:
txtDescr = description
else:
txtDescr = 'Dynare Model ' + name
elif ext.lower() == ".model":
txtEqs,txtParams,txtParamsRange,txtEndogVars,txtExogVars,txtShocks,txtRange,txtFreq,description = readIrisModelFile(file_path)
if description:
txtDescr = description
else:
txtDescr = 'Iris Model ' + name
elif ext.lower() == ".txt":
txtEqs,txtParams,txtParamsRange,txtEndogVars,txtExogVars,txtShocks,txtRange,txtFreq,description = readTemplateFile(file_path)
if description:
txtDescr = description
else:
txtDescr = 'Text File ' + name
elif ext.lower() == ".yaml":
txtEqs,txtParams,txtParamsRange,txtEndogVars,txtExogVars,txtShocks,varLabels,txtRange,txtFreq,description = readYamlModelFile(file_path)
if description:
txtDescr = description
else:
txtDescr = 'YAML Model ' + name
labels = varLabels
elif ext.lower() == ".xml":
txtEqs,txtParams,txtParamsRange,txtEndogVars,txtExogVars,txtShocks,txtRange,txtFreq,description = readXmlModelFile(file_path)
if description:
txtDescr = description
else:
txtDescr = 'XML Model ' + name
else:
txtEqs="";txtParams="";txtParamsRange="";txtEndogVars="";txtExogVars="";txtShocks="";txtRange="";txtFreq=""
txtDescr = 'UnknownL Model File Type'
messagebox.showwarning("Unknown Model File Extension","Only the following file extensions are supported: inp/mod/model/yaml/txt! You are trying to open file with extension: {}".format(ext))
lst = txtShocks.split('\n'); lst2 = []
for x in lst:
if ':' in x or '=' in x:
lst2.append(x.replace('=','= ').replace(':','= '))
else:
tmp = x.split(',')
for i in range(len(tmp)):
lst2.append(f'{tmp[i]} = 0')
txtShocks = '\n'.join(lst2)
return txtDescr,txtEqs,txtParams,txtParamsRange,txtEndogVars,txtExogVars,txtShocks,labels,txtRange,txtFreq,eqLabels,comments
[docs]
def checkNumberOfEquationsAndVariables(self):
"""
Performs check of equality of the number of equations
and of the number of variables
"""
input_file = self.input_file
b = not input_file is None and input_file.endswith(".inp")
var = getVariables(self)
if b:
var = [x.strip() for x in var if x.strip() and not "_ss" in x]
n_var = len(var)
eqs = getEquations(self)
if b:
eqs = [x.strip() for x in eqs if x.strip() and not "_ss" in x]
n_eqs = len(eqs)
if n_var < n_eqs:
msg = "endogenous variables"
elif n_var > n_eqs:
msg = "equations"
if n_var != n_eqs:
messagebox.showerror("Warning","Number of equations: {} and number of endogenous variables: {} is different. Please add {}.".format(n_eqs,n_var,msg))
return True
else:
return True
[docs]
def getDescription(self):
"""Return Description."""
description = self.description
return description
[docs]
def getShocks(self):
obj = self.containers[strShocks]
shocks = obj.get("1.0",tk.END)
tmp = shocks.split("\n")
shocks = list(filter(None,tmp))
return shocks
[docs]
def getShockNamesAndValues(self):
shocks = getShocks(self)
shock_names = []; shock_values = []
names, values = getNamesAndValues(shocks)
for n,v in zip(names, values):
if not "Date" in n:
shock_names.append(n)
shock_values.append(v)
return shock_names, shock_values
[docs]
def getVariableNamesAndInitialValues(self):
var = getVariables(self)
return getNamesAndValues(var)
[docs]
def getVariables(self):
obj = self.containers[strEndogVarInitValues]
var = obj.get("1.0",tk.END)
tmp = var.split("\n")
var = list(filter(None,tmp))
return var
[docs]
def getExogVariables(self):
obj = self.containers[strExogVariables]
exog_var = obj.get("1.0",tk.END)
tmp = exog_var.split("\n")
exog_var = list(filter(None,tmp))
return exog_var
[docs]
def getParameters(self):
obj = self.containers[strParams]
params = obj.get("1.0",tk.END)
tmp = params.split("\n")
params = list(filter(None,tmp))
return params
[docs]
def getParameterNamesAndValues(self):
params = getParameters(self)
return getNamesAndValues(params)
[docs]
def getParamRange(self):
obj = self.containers[strSteadyStates]
param_range = obj.get("1.0",tk.END)
param_range = param_range.split('\n')
param_range = list(filter(None,param_range))
return param_range
[docs]
def getEquations(self):
obj = self.containers[strEqs]
equations = obj.get("1.0",tk.END)
eqs = equations.split("\n")
eqs = [x for x in eqs if not x.strip().startswith("#")]
equations = list(filter(None,eqs))
return equations
[docs]
def getTimeRange(self):
obj = self.containers[strTimeRange]
time_range = obj.get("1.0",tk.END)
return time_range
[docs]
def getFrequency(self):
try:
obj = self.containers[strFreq]
selection = obj.curselection()
freq = obj.get(selection[0])
ind = strFreqList.index(freq)
if ind == -1:
ind = 0
except:
ind = 0
return str(ind)
[docs]
def getPeriods(self):
import pandas as pd
periods = []
shocks = getShocks(self)
rng = getTimeRange(self)
freq = getFrequency(self)
ind = -1
for shock in shocks:
ind = shock.find('Date')
if ind >= 0:
txt = shock[3+ind:]
ind2 = -1
if ":" in txt:
ind2 = txt.find(":")
if "=" in txt:
ind2 = txt.find("=")
if ind2 >= 0:
txt = txt[1+ind2:].strip()
period = dt.datetime.strptime(txt,'%m/%d/%Y')
frequencies = {"0":"YS","1":"QS","2":"MS","3":"W","4":"D"}
tmp = rng.split('-')
if len(tmp) == 2:
time_range = pd.date_range(start=tmp[0].strip(),end=tmp[1].strip(),freq=frequencies[freq])
for i,d in enumerate(time_range):
if d == period:
periods.append(i)
return periods
[docs]
def output(self,f,label,txt):
#print(txt)
f.write(label)
f.write('\n')
txt = txt.split('\n')
for i in range(len(txt)):
f.writelines(' ' + txt[i] + '\n')
f.write('\n')
[docs]
def SaveYamlOutput(self):
"""
Writes GUI data to YAML template text file
"""
from snowdrop.src.utils.util import SaveToYaml
description = self.description
shock_names,shock_values = getShockNamesAndValues(self)
variables_names,variables_init_values = getVariableNamesAndInitialValues(self)
param_names,param_values = getParameterNamesAndValues(self)
exog_var = getExogVariables(self)
equations = getEquations(self)
time_range = getFormattedTimeRange(self)
freq = getFrequency(self)
periods = getPeriods(self)
param_range = getParamRange(self)
input_file = self.input_file
bInp = not input_file is None and input_file.endswith(".inp")
fdir,fname = os.path.split(self.input_file)
self.temp_file = os.path.abspath(os.path.join(fdir,'../temp.yaml'))
SaveToYaml(file=self.temp_file,description=description,shock_names=shock_names,shock_values=shock_values,
variables_names=variables_names,variables_init_values=variables_init_values,comments=self.comments,
param_names=param_names,param_values=param_values,exog_var=exog_var,equations=equations,
varLabels=self.labels,time_range=time_range,freq=freq, periods=periods,
param_range=param_range,bInp=bInp)
[docs]
def SaveTemplateOutput(self):
"""
Write GUI data to template yaml file.
"""
path = os.path.dirname(os.path.abspath(__file__))
file_path = os.path.abspath(os.path.join(path, '../../../supplements/models/template.yaml'))
description = getDescription(self)
eqs = getEquations(self)
params = getParameters(self)
initValues = getVariables(self)
exogVariables = getExogVariables(self)
shocks = getShocks(self)
timeRange = getTimeRange(self)
freq = getFrequency(self)
eqs = '\n'.join(eqs).replace(' ','').replace('=',' = ')
params = '\n'.join(params).replace(' ','').replace('=',': ')
initValues = '\n'.join(initValues).replace(' ','').replace('=',': ')
exogVariables ='\n'.join(exogVariables).replace(' ','').replace('=',': ')
shocks = '\n'.join(shocks).replace(' ','').replace('=',': ')
timeRange = timeRange.replace(':',': ').replace('=',': ')
with open(file_path, 'w') as f:
output(self,f,strDescription,description)
output(self,f,strEqs,eqs)
output(self,f,strParams,params)
output(self,f,strEndogVarInitValues,initValues)
output(self,f,strExogVariables,exogVariables)
output(self,f,strShocks,shocks)
output(self,f,strTimeRange,timeRange)
output(self,f,strFreq,freq)
if __name__ == '__main__':
path = os.path.dirname(os.path.abspath(__file__))
working_dir = os.path.abspath(os.path.join(path,"../../.."))
sys.path.append(working_dir)
file_path = os.path.abspath(os.path.join(working_dir,'supplements/models/TOY/JLMP98.yaml'))
root = tk.Tk()
app = Application(root)
app.master.title("Equations Editor")
app.master.minsize(minWidth, minHeight)
app.master.maxsize(maxWidth, maxHeight)
app.mainloop()