function varargout = DynamicNeuralFieldModel(varargin)
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
    'gui_Singleton',  gui_Singleton, ...
    'gui_OpeningFcn', @DynamicNeuralFieldModel_OpeningFcn, ...
    'gui_OutputFcn',  @DynamicNeuralFieldModel_OutputFcn, ...
    'gui_LayoutFcn',  [] , ...
    'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT



function DynamicNeuralFieldModel_OpeningFcn(hObject, eventdata, handles, varargin)
%% Executes just before DynamicNeuralFieldModel is made visible.
handles.output = hObject;
guidata(hObject, handles);
cla(handles.Axis_2D);
set(gcf, 'ToolBar', 'auto')


function varargout = DynamicNeuralFieldModel_OutputFcn(hObject, eventdata, handles)
%% Outputs from this function are returned to the command line.
varargout{1} = handles.output;


function PlotButton_Callback(hObject, eventdata, handles)
% clearing axes
cla(handles.Axis_2D);

% model parameters
nn = str2num(get(handles.NodeInput,'String'));
dx=2*pi/nn; mu=50;
sig = str2num(get(handles.SigmaInput,'String'))*pi;
Aw=str2num(get(handles.AwInput,'String')); % default 4
C=str2num(get(handles.InhibitionInput,'String')); % default 0.5
h=str2num(get(handles.h_Input,'String'));

% experimental parameters
tstart=str2num(get(handles.StartTime,'String')); % start time (current off)
tend=str2num(get(handles.EndTime,'String')); % end time (current off)
currentOffAt=str2num(get(handles.I_extOff,'String')); % time to switch current on
currentOnAt=str2num(get(handles.I_extOn,'String')); % time to switch current off

if tstart<=currentOnAt&&currentOnAt<=currentOffAt&& currentOffAt<=tend
    set(handles.errorString,'String','');
%% Training weight matrix
for loc=1:nn;
    i=(1:nn)'; dis=min(abs(i-loc),nn-abs(i-loc));
    pat(:,loc)=exp(-(dis*dx).^2/(2*sig^2));
end
w=pat*pat'; w=w/w(1,1); w=Aw*(w-C);

tall = []; rall = [];

%% Finding I_ext
numGaus=str2num(get(handles.numGaussians,'String'));
sig=zeros(1,numGaus); mu=zeros(1,numGaus); Amp=zeros(1,numGaus);
if numGaus>=1
    sig(1)=str2num(get(handles.sigma1,'String')); mu(1)=str2num(get(handles.mu1,'String')); Amp(1)=str2num(get(handles.Amp1,'String'));
    if numGaus>=2
        sig(2)=str2num(get(handles.sigma2,'String')); mu(2)=str2num(get(handles.mu2,'String')); Amp(2)=str2num(get(handles.Amp2,'String'));
        if numGaus>=3
            sig(3)=str2num(get(handles.sigma3,'String')); mu(3)=str2num(get(handles.mu3,'String')); Amp(3)=str2num(get(handles.Amp3,'String'));
            if numGaus>=4
                sig(4)=str2num(get(handles.sigma4,'String')); mu(4)=str2num(get(handles.mu4,'String')); Amp(4)=str2num(get(handles.Amp4,'String'));
            end
        end
    end
end

sig=sig*pi; mu=mu*pi;

% finding individual gaussian functions according to inputted parameters.
I_ext=zeros(length(dx:dx:w*pi),numGaus);
for i=1:numGaus
    I_ext(:,i)=[dx:dx:2*pi]';
    I_ext(:,i)=Amp(i)*exp((-1)*((I_ext(:,i).^2-2*I_ext(:,i)*mu(i)+mu(i)^2)/(2*sig(i)^2)));
end
% summing gaussian functions to create a single input
summed_I_ext=sum(I_ext,2); % summing rows

%% Update without input
summed_I_ext0=zeros(nn,1); % matrix of 0 input.
[t,u]=ode45('rnn_ode',[tstart currentOnAt],zeros(1,nn),[],nn,dx,w,summed_I_ext0,h);
r=1./(1+exp(-u)); tall=[tall;t]; rall=[rall;r];


%% Update with localised input
% using earlier calculated current input (summed_I_ext)
[t,u]=ode45('rnn_ode',[currentOnAt currentOffAt],u(size(u,1),:),[],nn,dx,w,summed_I_ext,h);
r=1./(1+exp(-u)); tall=[tall;t]; rall=[rall;r];

%% Update without input
% using matrix of 0 input
[t,u]=ode45('rnn_ode',[currentOffAt tend],u(size(u,1),:),[],nn,dx,w,summed_I_ext0,h);
r=1./(1+exp(-u)); tall=[tall;t]; rall=[rall;r];

%% Plotting results

set(handles.Axis_3D,'Visible','on');
set(handles.Axis_2D,'Visible','on');
set(handles.nodeLabel,'Visible','on');
set(handles.rLegend1,'Visible','on'); set(handles.rLegend2,'Visible','on');
set(handles.rLegend2,'Position',[98 17.673 8.4 0.6923]);
% 2D Axis parameters
time=length(tall);
miny=min(min(min(rall)), min(summed_I_ext)); miny=min(miny,0);
maxy=max(max(max(rall)), max(summed_I_ext));

timeOn=sum(tall<currentOnAt);
timeOff=sum(tall<currentOffAt);
ylim(handles.Axis_2D, [miny maxy]);

i=1;
plot(handles.Axis_2D, dx:dx:2*pi, rall(i,:));
title(handles.Axis_2D,['t=', num2str(tall(i))],'Fontsize', 12);
ylim(handles.Axis_2D, [miny maxy]); xlim(handles.Axis_2D,[0 2*pi]);
set(handles.Axis_2D,'XTick',0:pi/4:2*pi)
set(handles.Axis_2D,'XTickLabel',{'0','pi/4','pi/2','3*pi/4','pi','5*pi/4','3*pi/2','7*pi/4', '2*pi'});

for i=2:timeOn
    plot(handles.Axis_2D, dx:dx:2*pi, rall(i,:));
    title(handles.Axis_2D,['t=', num2str(tall(i))],'Fontsize', 12);
    ylim(handles.Axis_2D, [miny maxy]); xlim(handles.Axis_2D,[0 2*pi]);
    set(handles.Axis_2D,'XTick',0:pi/4:2*pi)
    set(handles.Axis_2D,'XTickLabel',{'0','pi/4','pi/2','3*pi/4','pi','5*pi/4','3*pi/2','7*pi/4', '2*pi'});
    
    surf(handles.Axis_3D,tall(1:i)',dx:dx:2*pi,rall(1:i,:)','linestyle','none');
    xlim(handles.Axis_3D,[1 tall(time)]); ylim(handles.Axis_3D,[dx 2*pi]); zlim(handles.Axis_3D, [miny maxy]);
    xlabel(handles.Axis_3D,'Time'); ylabel(handles.Axis_3D,'Nodes'); zlabel(handles.Axis_3D,'Rate');
    set(handles.Axis_3D,'YTick',0:pi/2:2*pi)
    set(handles.Axis_3D,'YTickLabel',{'0','pi/2','pi','3*pi/2','2*pi'});
    view(handles.Axis_3D,get(handles.horizontalViewSlider,'Value'), get(handles.verticalViewSlider,'Value'));
    pause(0.01);
    
end
set(handles.eiLegend1,'Visible','on'); set(handles.eiLegend2,'Visible','on');
for i=timeOn+1:timeOff
    plot(handles.Axis_2D,  dx:dx:2*pi, rall(i,:), dx:dx:2*pi, summed_I_ext');
    title(handles.Axis_2D,['t=', num2str(tall(i))],'Fontsize', 12);
    ylim(handles.Axis_2D, [miny maxy]); xlim(handles.Axis_2D,[0 2*pi]);
    set(handles.Axis_2D,'XTick',0:pi/4:2*pi)
    set(handles.Axis_2D,'XTickLabel',{'0','pi/4','pi/2','3*pi/4','pi','5*pi/4','3*pi/2','7*pi/4', '2*pi'});
    
    surf(handles.Axis_3D,tall(1:i)',dx:dx:2*pi,rall(1:i,:)','linestyle','none');
    xlim(handles.Axis_3D,[1 tall(time)]); ylim(handles.Axis_3D,[dx 2*pi]); zlim(handles.Axis_3D, [miny maxy]);
    xlabel(handles.Axis_3D,'Time'); ylabel(handles.Axis_3D,'Nodes'); zlabel(handles.Axis_3D,'Rate');
    set(handles.Axis_3D,'YTick',0:pi/2:2*pi)
    set(handles.Axis_3D,'YTickLabel',{'0','pi/2','pi','3*pi/2','2*pi'});
    view(handles.Axis_3D,get(handles.horizontalViewSlider,'Value'), get(handles.verticalViewSlider,'Value'));
    pause(0.01);
end
set(handles.eiLegend1,'Visible','off'); set(handles.eiLegend2,'Visible','off');
for i=timeOff+1:time
    plot(handles.Axis_2D,dx:dx:2*pi, rall(i,:));
    title(handles.Axis_2D,['t=', num2str(tall(i))],'Fontsize', 12);
    ylim(handles.Axis_2D, [miny maxy]);
    xlim(handles.Axis_2D,[0 2*pi]);
    set(handles.Axis_2D,'XTick',0:pi/4:2*pi)
    set(handles.Axis_2D,'XTickLabel',{'0','pi/4','pi/2','3*pi/4','pi','5*pi/4','3*pi/2','7*pi/4', '2*pi'});
    
    surf(handles.Axis_3D,tall(1:i)',dx:dx:2*pi,rall(1:i,:)','linestyle','none');
    xlim(handles.Axis_3D,[1 tall(time)]); ylim(handles.Axis_3D,[dx 2*pi]); zlim(handles.Axis_3D, [miny maxy]);
    xlabel(handles.Axis_3D,'Time'); ylabel(handles.Axis_3D,'Nodes'); zlabel(handles.Axis_3D,'Rate');
    set(handles.Axis_3D,'YTick',0:pi/2:2*pi)
    set(handles.Axis_3D,'YTickLabel',{'0','pi/2','pi','3*pi/2','2*pi'});
    view(handles.Axis_3D,get(handles.horizontalViewSlider,'Value'), get(handles.verticalViewSlider,'Value'));
    pause(0.01);
end
else
    set(handles.errorString,'String','Invalid experimental parameters input');
end



function numGaussians_Callback(hObject, eventdata, handles)
n=str2num(get(handles.numGaussians,'String'));
if n>4||n<0
    set(handles.errorString,'String','Number must be between 0 and 4');
    set(handles.errorString,'Visible','on');
else
      set(handles.sigma1,'Visible','off');
    set(handles.mu1,'Visible','off');
    set(handles.Amp1,'Visible','off');
    set(handles.G1Label,'Visible','off');
    
    set(handles.sigma2,'Visible','off');
    set(handles.mu2,'Visible','off');
    set(handles.Amp2,'Visible','off');
    set(handles.G2Label,'Visible','off');
    
    set(handles.sigma3,'Visible','off');
    set(handles.mu3,'Visible','off');
    set(handles.Amp3,'Visible','off');
    set(handles.G3Label,'Visible','off');
    
    set(handles.mu4,'Visible','off');
    set(handles.sigma4,'Visible','off');
    set(handles.Amp4,'Visible','off');
    set(handles.G4Label,'Visible','off');
    
    set(handles.pi1,'Visible','off');
    set(handles.pi11,'Visible','off');
    set(handles.pi2,'Visible','off');
    set(handles.pi22,'Visible','off');
    set(handles.pi3,'Visible','off');
    set(handles.pi33,'Visible','off');
    set(handles.pi4,'Visible','off');
    set(handles.pi44,'Visible','off');
    
    
    
    if n>=1
        set(handles.sigma1,'Visible','on');
        set(handles.mu1,'Visible','on');
        set(handles.Amp1,'Visible','on');
        set(handles.G1Label,'Visible','on');
        set(handles.pi1,'Visible','on');
        set(handles.pi11,'Visible','on');
        if n>=2
            set(handles.sigma2,'Visible','on');
            set(handles.mu2,'Visible','on');
            set(handles.Amp2,'Visible','on');
            set(handles.G2Label,'Visible','on');
            set(handles.pi2,'Visible','on');
            set(handles.pi22,'Visible','on');
            if n>=3
                set(handles.sigma3,'Visible','on');
                set(handles.mu3,'Visible','on');
                set(handles.Amp3,'Visible','on');
                set(handles.G3Label,'Visible','on');
                set(handles.pi3,'Visible','on');
                set(handles.pi33,'Visible','on');
                if n>=4
                    set(handles.mu4,'Visible','on');
                    set(handles.sigma4,'Visible','on');
                    set(handles.Amp4,'Visible','on');
                    set(handles.G4Label,'Visible','on');
                    set(handles.pi4,'Visible','on');
                    set(handles.pi44,'Visible','on');
                end
            end
        end
    end
end

function NodeInput_Callback(hObject, eventdata, handles)
function NodeInput_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function SigmaInput_Callback(hObject, eventdata, handles)
function SigmaInput_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function AwInput_Callback(hObject, eventdata, handles)
function AwInput_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function InhibitionInput_Callback(hObject, eventdata, handles)
function InhibitionInput_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


function numGaussians_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
function sigma1_Callback(hObject, eventdata, handles)
if str2num(get(handles.sigma1,'String'))==0
    set(handles.errorString,'String','Sigma cannot be 0');
    set(handles.errorString,'Visible','on');
else
    set(handles.errorString,'String','');
end
function sigma1_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function sigma4_Callback(hObject, eventdata, handles)
if str2num(get(handles.sigma4,'String'))==0
    set(handles.errorString,'String','Sigma cannot be 0');
    set(handles.errorString,'Visible','on');
else
    set(handles.errorString,'String','');
end

function sigma4_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function mu4_Callback(hObject, eventdata, handles)
function mu4_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function sigma3_Callback(hObject, eventdata, handles)
if str2num(get(handles.sigma3,'String'))==0
    set(handles.errorString,'String','Sigma cannot be 0');
    set(handles.errorString,'Visible','on');
else
    set(handles.errorString,'String','');
end
function sigma3_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function mu2_Callback(hObject, eventdata, handles)
function mu2_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function mu3_Callback(hObject, eventdata, handles)
function mu3_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function sigma2_Callback(hObject, eventdata, handles)
if str2num(get(handles.sigma2,'String'))==0
    set(handles.errorString,'String','Sigma cannot be 0');
    set(handles.errorString,'Visible','on');
else
    set(handles.errorString,'String','');
end
function sigma2_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function mu1_Callback(hObject, eventdata, handles)
function mu1_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


function ResetButton_Callback(hObject, eventdata, handles)
% clearing graphs & legends
cla(handles.Axis_2D);
cla(handles.Axis_3D);
set(handles.eiLegend1,'Visible','off');
set(handles.eiLegend2,'Visible','off');
set(handles.rLegend1,'Visible','off');
set(handles.rLegend2,'Visible','off');

% resetting model parameters
set(handles.NodeInput,'String', num2str(100));
set(handles.SigmaInput,'String', num2str(0.2));
set(handles.AwInput,'String',num2str(4));
set(handles.InhibitionInput,'String',num2str(0.5));
set(handles.h_Input,'String', num2str(0));
set(handles.StartTime,'String',num2str(0));
set(handles.I_extOn,'String',num2str(5));
set(handles.I_extOff,'String', num2str(15));
set(handles.EndTime,'String',num2str(30));
set(handles.horizontalViewSlider,'Value',45);
set(handles.horizontalViewSlider,'Value',45);

% resetting number of gaussians used
set(handles.numGaussians,'String',num2str(1));
numGaussians_Callback(hObject, eventdata, handles);

defaultSigma=0.25; defaultMu=0.5;
% resetting sigmas
set(handles.sigma1,'String',num2str(defaultSigma));
set(handles.sigma2,'String',num2str(defaultSigma));
set(handles.sigma3,'String',num2str(defaultSigma));
set(handles.sigma4,'String',num2str(defaultSigma));

% reseting mus
set(handles.mu1,'String',num2str(1*defaultMu));
set(handles.mu2,'String',num2str(0*defaultMu));
set(handles.mu3,'String',num2str(0.5*defaultMu));
set(handles.mu4,'String',num2str(1.5*defaultMu));


function Amp1_Callback(hObject, eventdata, handles)
function Amp1_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function Amp2_Callback(hObject, eventdata, handles)
function Amp2_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function Amp3_Callback(hObject, eventdata, handles)
function Amp3_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function Amp4_Callback(hObject, eventdata, handles)
function Amp4_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function I_extOff_Callback(hObject, eventdata, handles)
function I_extOff_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function StartTime_Callback(hObject, eventdata, handles)

function StartTime_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function EndTime_Callback(hObject, eventdata, handles)
function EndTime_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function CloseButton_Callback(hObject, eventdata, handles)
close(handles.figure1);
close all; clear all;

function I_extOn_Callback(hObject, eventdata, handles)
function I_extOn_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function h_Input_Callback(hObject, eventdata, handles)
function h_Input_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

function PlotHistory_Callback(hObject, eventdata, handles)




function horizontalViewSlider_Callback(hObject, eventdata, handles)
view(handles.Axis_3D,get(handles.horizontalViewSlider,'Value'), get(handles.verticalViewSlider,'Value'));
function horizontalViewSlider_CreateFcn(hObject, eventdata, handles)
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end

function verticalViewSlider_Callback(hObject, eventdata, handles)
view(handles.Axis_3D,get(handles.horizontalViewSlider,'Value'), get(handles.verticalViewSlider,'Value'));



function verticalViewSlider_CreateFcn(hObject, eventdata, handles)
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end
