function [Ep,Cp,K1,K2] = spm_hdm_ui(xSPM,SPM,hReg)
% User interface for hemodynamic model estimation
% FORMAT [Ep,Cp,K1,K2] = spm_hdm_ui(xSPM,SPM,hReg
%
% xSPM   - structure containing specific SPM details
% SPM    - structure containing generic  SPM details
% hReg   - Handle of results section XYZ registry (see spm_results_ui.m)
%
% Ep     - conditional expectations of the hemodynamic model parameters
% Cp     - conditional  covariance  of the hemodynamic model parameters
% K1     - 1st order kernels
% K2     - 2nd order kernels
%          (see main body of routine for details of model specification)
%__________________________________________________________________________
% Copyright (C) 2005-2013 Wellcome Trust Centre for Neuroimaging

% Karl Friston
% $Id: spm_hdm_ui.m 6314 2015-01-23 17:00:51Z guillaume $


% get figure handles
%--------------------------------------------------------------------------
Finter = spm_figure('GetWin','Interactive');
header = get(Finter,'Name');
set(Finter,'Name','Hemodynamic modelling')

% inputs
%==========================================================================

% which session?
%--------------------------------------------------------------------------
s    = length(SPM.Sess);
if s > 1
    s = spm_input('which session',1,'n1',s,s);
end
Sess = SPM.Sess(s);

% 'causes' or imputs U
%--------------------------------------------------------------------------
spm_input('Input specification:...  ',1,'d');
U.dt = Sess.U(1).dt;
u    = length(Sess.U);
if u == 1 && length(Sess.U(1).name) == 1
    U.name = Sess.U(1).name;
    U.u    = Sess.U(1).u(33:end,1);
else
    U.name = {};
    U.u    = [];
    for  i = 1:u
    for  j = 1:length(Sess.U(i).name)
        str   = ['include ' Sess.U(i).name{j} '?'];
        if spm_input(str,2,'y/n',[1 0])
            U.u             = [U.u Sess.U(i).u(33:end,j)];
            U.name{end + 1} = Sess.U(i).name{j};
        end
    end
    end
end

%-Echo time (TE) of data acquisition
%--------------------------------------------------------------------------
TE    = 0.04;
TE_ok = 0;
while ~TE_ok
    TE = spm_input('Echo time, TE [s]', '+1', 'r', TE);
    if ~TE || (TE < 0) || (TE > 0.1)
        str = { 'Extreme value for TE or TE undefined.',...
            'Please re-enter TE (in seconds!)'};
        spm_input(str,'+1','bd','OK',[1],1);
    else
        TE_ok = 1;
    end
end

    
%-System outputs
%==========================================================================

% enforce adjustment w.r.t. all effects
%--------------------------------------------------------------------------
xY     = struct(    'Ic'        ,0,...  
                    'name'      ,'HDM',...
                    'Sess'      ,s);

% get region stucture
%--------------------------------------------------------------------------
xY     = struct('name', 'HDM', 'Sess', s);
[y,xY] = spm_regions(xSPM,SPM,hReg,xY);

% place response and confounds in response structure
%--------------------------------------------------------------------------
y      = xY.u;
Y.y    = y;
Y.dt   = SPM.xY.RT;
Y.X0   = xY.X0;

%-Estimate
%==========================================================================
spm('Pointer','Watch')
spm('FigName','Estimation in progress');


% Model specification: m input; 4 states; 1 outout; m + 6 parameters
%--------------------------------------------------------------------------
% u(m) - mth stimulus function     (u)
%
% x(1) - vascular signal           log(s)
% x(2) - rCBF                      log(f)
% x(3) - venous volume             log(v)
% x(4) - deoyxHb                   log(q)
%
% y(1) - BOLD                      (y)
%
% P(1)       - signal decay               d(ds/dt)/ds)      half-life = log(2)/P(1) ~ 1sec
% P(2)       - autoregulation             d(ds/dt)/df)      2*pi*sqrt(1/P(1)) ~ 10 sec
% P(3)       - transit time               (t0)              ~ 1 sec
% P(4)       - exponent for Fout(v)       (alpha)           c.f. Grubb's exponent (~ 0.38)
% P(5)       - resting oxygen extraction  (E0)              ~ range 20 - 50%
% P(6)       - ratio of intra- to extra-  (epsilon)         ~ range 0.5 - 2
%              vascular components   
%              of the gradient echo signal   

% P(6 + 1:m) - input efficacies - d(ds/dt)/du)  ~0.3 per event
%--------------------------------------------------------------------------

% priors (3 modes of hemodynamic variation)
%--------------------------------------------------------------------------
m       = size(U.u,2);
[pE,pC] = spm_hdm_priors(m,3);

% model
%--------------------------------------------------------------------------
M.f     = 'spm_fx_hdm';
M.g     = 'spm_gx_hdm';
M.x     = [0 0 0 0]'; 
M.pE    = pE;    
M.pC    = pC;
M.m     = m;
M.n     = 4;
M.l     = 1;
M.N     = 64;
M.dt    = 24/M.N;
M.TE    = TE;

% nonlinear system identification
%--------------------------------------------------------------------------
[Ep,Cp,Ce,K0,K1,K2,M0,M1] = spm_nlsi(M,U,Y);

%-display results
%==========================================================================
t       = [1:M.N]*M.dt;
Fhdm    = spm_figure;
set(Fhdm,'name','Hemodynamic Modeling')


% display input parameters
%--------------------------------------------------------------------------
subplot(2,2,1)
P     = Ep(7:end);
C     = diag(Cp(7:end,7:end));
[i,j] = max(abs(P));
spm_barh(P,C)
axis square
title({'stimulus efficacy'; 'with 90% confidence intervals'},'FontSize',10)
set(gca,'Ytick',[1:m],'YTickLabel',U.name,'FontSize',8)
str = {};
for i = 1:m
    str{end + 1} = U.name{i};
    str{end + 1} = sprintf('mean = %0.2f',P(i));
    str{end + 1} = '';
end
set(gca,'Ytick',[1:m*3]/3 + 1/2,'YTickLabel',str)
xlabel('relative efficacy per event/sec')


% display hemodynamic parameters
%--------------------------------------------------------------------------
subplot(2,2,3)
P     = Ep(1:6);
pE    = pE(1:6);
C     = diag(Cp(1:6,1:6));
spm_barh(P,C,pE)
title({ 'hemodynamic parameters'},'FontSize',10)
set(gca,'Ytick',[1:18]/3 + 1/2)
set(gca,'YTickLabel',{  'SIGNAL decay',...
             sprintf('%0.2f per sec',P(1)),'',...
            'FEEDBACK',...
             sprintf('%0.2f per sec',P(2)),'',...
            'TRANSIT TIME',...
             sprintf('%0.2f seconds',P(3)),'',...
            'EXPONENT',...
             sprintf('%0.2f',P(4)),'',...
            'EXTRACTION',...
             sprintf('%0.0f %s',P(5)*100,'%'),'',...
            'log SIGNAL RATIO',...
             sprintf('%0.2f %s',P(6),'%'),''},'FontSize',8)


% get display state kernels (i.e. state dynamics) 
%==========================================================================

% Volterra kernels of states
%--------------------------------------------------------------------------
[H0,H1] = spm_kernels(M0,M1,M.N,M.dt);

subplot(3,2,2)
plot(t,exp(H1(:,:,j)))
axis square
title({['1st order kernels for ' U.name{j}];...
       'state variables'},'FontSize',9)
ylabel('normalized values')
legend({'s','f','v','q'}, 'Location','Best');
grid on


% display output kernels (i.e. BOLD response) 
%--------------------------------------------------------------------------
subplot(3,2,4)
plot(t,K1(:,:,j))
axis square
title({'1st order kernel';...
       'output: BOLD'},'FontSize',9)
ylabel('normalized flow signal')
grid on

subplot(3,2,6)
imagesc(t,t,K2(:,:,1,j,j))
axis square
title({'2nd order kernel';...
       'output: BOLD'},'FontSize',9)
xlabel({'time \{seconds\} for'; U.name{j}})
grid on


%-Reset title
%--------------------------------------------------------------------------
spm('FigName',header);
spm('Pointer','Arrow')
spm_input('Thank you',1,'d')
