diff --git a/src/+gui_tools/menu_options.m b/src/+gui_tools/menu_options.m index 10fdc606807dd9dbc1e92a1e813cc5195b4584b6..c022a47eba9daf61612a7193e8d3f7b84297d607 100644 --- a/src/+gui_tools/menu_options.m +++ b/src/+gui_tools/menu_options.m @@ -71,6 +71,7 @@ switch oid case 'sensitivity' handles.model_export.Enable = status; handles.sensitivity_analysis.Enable = status; + handles.irf_calibration.Enable = status; case 'output' if strcmpi(status, 'off') diff --git a/src/dynare_gui.m b/src/dynare_gui.m index a52ede96121d482d7ca83ce2ee8776e96981af92..8f5725f995062ec85b202531baff77477164c98d 100644 --- a/src/dynare_gui.m +++ b/src/dynare_gui.m @@ -316,6 +316,11 @@ possibly_create_model_settings(); gui_sensitivity_analysis(addTab(hObject, 'Sensitivity', handles)); end +function irf_calibration_Callback(hObject, ~, handles) +possibly_create_model_settings(); +gui_irf_calibration(addTab(hObject, 'IRF Calibration', handles)); +end + % Output! function output_shock_decomposition_Callback(hObject, ~, handles) gui_shock_decomposition(addTab(hObject, 'Shock decomp. ', handles)); @@ -706,6 +711,18 @@ uimenu(... 'Tag','sensitivity_analysis',... 'CreateFcn', {@local_CreateFcn, blanks(0), appdata} ); +appdata = []; +appdata.lastValidTag = 'irf_calibration'; + +uimenu(... + 'Parent',h24,... + 'Enable','off',... + 'Callback',@(hObject,eventdata)dynare_gui('irf_calibration_Callback',hObject,eventdata,guidata(hObject)),... + 'Label','Irf Calibration',... + 'Tag','irf_calibration',... + 'CreateFcn', {@local_CreateFcn, blanks(0), appdata} ); + + appdata = []; appdata.lastValidTag = 'uipanel_welcome'; diff --git a/src/gui_irf_calibration.m b/src/gui_irf_calibration.m new file mode 100644 index 0000000000000000000000000000000000000000..7aa57164e2f01d474584a45463c33fbfaea931a9 --- /dev/null +++ b/src/gui_irf_calibration.m @@ -0,0 +1,233 @@ +function gui_irf_calibration(tabId) +% function gui_irf_calibration(tabId) +% interface for the DYNARE irf_calibration command +% +% INPUTS +% tabId: GUI tab element which displays the irf_calibration interface +% +% OUTPUTS +% none +% +% SPECIAL REQUIREMENTS +% none + +% Copyright (C) 2019 Dynare Team +% +% This file is part of Dynare. +% +% Dynare is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% Dynare is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with Dynare. If not, see <http://www.gnu.org/licenses/>. + +global model_settings options_ + +handles = []; +gui_size = gui_tools.get_gui_elements_size(tabId); + +uicontrol( ... + tabId, ... + 'Tag', 'pushbuttonSimulation', ... + 'Style', 'pushbutton', ... + 'Units', 'normalized', ... + 'Position', [gui_size.space gui_size.bottom gui_size.button_width_small gui_size.button_height], ... + 'String', 'Run IRF Calibration', ... + 'Callback', @call_irf_calibration); + +uicontrol( ... + tabId, ... + 'Tag', 'pushbuttonReset', ... + 'Style', 'pushbutton', ... + 'Units', 'normalized', ... + 'Position', [gui_size.space*2+gui_size.button_width_small gui_size.bottom gui_size.button_width_small gui_size.button_height], ... + 'String', 'Reset', ... + 'Callback', @reset); + +uicontrol( ... + tabId, ... + 'Tag', 'pushbuttonReset', ... + 'Style', 'pushbutton', ... + 'Units', 'normalized', ... + 'Position', [gui_size.space*3+gui_size.button_width_small*2 gui_size.bottom gui_size.button_width_small gui_size.button_height], ... + 'String', 'Close Tab', ... + 'Callback', {@close_tab, tabId}); + +handles.uipanelShocks = uipanel( ... + tabId, ... + 'Tag', 'uipanelShocks', ... + 'Units', 'normalized', ... + 'Position', [0.01 0.1 .99 0.9], ... + 'Title', '', ... + 'BorderType', 'none'); + +handles.shocksTabGroup = uitabgroup( ... + handles.uipanelShocks, ... + 'Position', [0 0 1 1]); +handles.shocks_tab = uitab( ... + handles.shocksTabGroup, ... + 'Title', 'Shocks', ... + 'UserData', 1); +handles.var_panel = uipanel( ... + handles.shocks_tab, ... + 'BorderType', 'none'); + +uicontrol( ... + handles.var_panel, ... + 'Style', 'text', ... + 'Units', 'normalized', ... + 'Position', [0.02 0.85 0.96 0.1], ... + 'FontWeight', 'bold', ... + 'String', 'Select variable and shock to define IRF calibration criteria.', ... + 'HorizontalAlignment', 'left'); + + +handles.relative_irf = uicontrol( ... + handles.var_panel, ... + 'Style', 'checkbox', ... + 'Units', 'normalized', ... + 'Position', [0.02 0.82 0.96 0.1], ... + 'String', 'relative_irf.', ... + 'HorizontalAlignment', 'left'); + +endogs = model_settings.variables(:, 3); +list_endogs = uicontrol( ... + handles.var_panel, ... + 'Style', 'popupmenu', ... + 'Units', 'normalized', ... + 'Position', [0.02 0.77 0.3 0.06], ... + 'String', ['Select endog...'; endogs], ... + 'Callback', @varlist_selection_changed); + +shocks = model_settings.shocks(:, 3); +list_shocks = uicontrol( ... + handles.var_panel, ... + 'Style', 'popupmenu', ... + 'Units', 'normalized', ... + 'Position', [0.36 0.77 0.3 0.06], ... + 'String', ['Select shock...'; shocks], ... + 'Callback', @varlist_selection_changed); + +handles.add_var = uicontrol( ... + handles.var_panel, ... + 'Style', 'pushbutton', ... + 'Units', 'normalized', ... + 'Position', [0.73 0.77 0.25 0.06], ... + 'String', 'Add ...', ... + 'Enable', 'Off', ... + 'Callback', @add_var); + +handles.table = uitable(handles.var_panel, ... + 'Units', 'normalized', ... + 'Position', [0.02 0.10 0.96 0.6], ... + 'ColumnName', {'Varibale', 'Start Period', 'End Period', 'Exogenous', 'Sign', 'Start Interval', 'End Interval', 'Remove'}, ... + 'ColumnFormat', {'char', 'numeric', 'numeric', 'char', 'char', 'numeric', 'numeric', 'logical'}, ... + 'ColumnEditable', [false, true, true, false, true, true, true, true], ... + 'RowName', [], ... + 'CellEditCallback', @savedata); + +handles.remove_all_selected = uicontrol( ... + handles.var_panel, ... + 'Style', 'pushbutton', ... + 'Units', 'normalized', ... + 'Position', [0.73 0.03 0.25 0.06], ... + 'String', 'Remove all selected', ... + 'Enable', 'Off', ... + 'Callback', @remove); + + function varlist_selection_changed(~, ~) + if list_shocks.Value > 1 && list_endogs.Value > 1 + handles.add_var.Enable = 'On'; + else + handles.add_var.Enable = 'Off'; + end + end + + function add_var(~, ~) + if list_shocks.Value > 1 && list_endogs.Value > 1 + handles.table.Data{end+1, 1} = endogs{list_endogs.Value-1}; + handles.table.Data{end, 2} = ''; + handles.table.Data{end, 3} = ''; + handles.table.Data{end, 4} = shocks{list_shocks.Value-1}; + handles.table.Data{end, 5} = ''; + handles.table.Data{end, 6} = ''; + handles.table.Data{end, 7} = ''; + handles.table.Data{end, 8} = false; + end + end + + function remove(~, ~) + handles.table.Data = ... + handles.table.Data(not([handles.table.Data{:, 8}]), :); + end + + function savedata(~, callbackdata) + if callbackdata.Indices(2) == 2 || callbackdata.Indices(2) == 3 + if isnan(str2double(callbackdata.NewData)) ... + || str2double(callbackdata.NewData) < 0 + handles.table.Data{callbackdata.Indices(1), callbackdata.Indices(2)} = ... + callbackdata.PreviousData; + end + elseif callbackdata.Indices(2) == 5 + if ~strcmp(callbackdata.NewData, '-') ... + && ~strcmp(callbackdata.NewData, '+') + handles.table.Data{callbackdata.Indices(1), callbackdata.Indices(2)} = ... + callbackdata.PreviousData; + end + elseif callbackdata.Indices(2) == 6 || callbackdata.Indices(2) == 7 + if isnan(str2double(callbackdata.NewData)) + handles.table.Data{callbackdata.Indices(1), callbackdata.Indices(2)} = ... + callbackdata.PreviousData; + end + elseif callbackdata.Indices(2) == 8 + if any([handles.table.Data{:, 8}]) + handles.remove_all_selected.Enable = 'On'; + else + handles.remove_all_selected.Enable = 'Off'; + end + end + end + + function reset(~, ~) + handles.table.Data = cell(0, 8); + end + + function call_irf_calibration(~, ~) + if handles.relative_irf.Value + options_.relative_irf = true; + else + options_.relative_irf = false; + end + r = rows(handles.table.Data); + options_.endogenous_prior_restrictions.irf = cell(r, 4); + for i = 1:r + options_.endogenous_prior_restrictions.irf{i, 1} = handles.table.Data{i, 1}; + options_.endogenous_prior_restrictions.irf{i, 2} = handles.table.Data{i, 4}; + if str2double(handles.table.Data{i, 2}) == str2double(handles.table.Data{i, 3}) + options_.endogenous_prior_restrictions.irf{i, 3} = str2double(handles.table.Data{i, 2}); + else + options_.endogenous_prior_restrictions.irf{i, 3} = str2double(handles.table.Data{i, 2}):str2double(handles.table.Data{i, 3}); + end + if isempty(handles.table.Data{i, 5}) + options_.endogenous_prior_restrictions.irf{i, 4} = [str2double(handles.table.Data{i, 6}), str2double(handles.table.Data{i, 7})]; + else + if strcmp(handles.table.Data{i, 5}, '+') + options_.endogenous_prior_restrictions.irf{i, 4} = [0 inf]; + else + options_.endogenous_prior_restrictions.irf{i, 4} = [-inf 0]; + end + end + end + end +end + +function close_tab(~, ~, hTab) +gui_tabs.delete_tab(hTab); +end