function [y,lfp,csd,w] = spm_gen_fmri(P,M,U) % Generates a prediction of (multimodal) source activity % FORMAT [y,lfp,csd,w] = spm_gen_fmri(P,M,U) % % P - parameters % M - neural-mass model structure % U - trial-effects % U.u - inputs % U.dt - (micro) time bins for within-trial effects % % y - BOLD predictions (for every TR) % lfp - voltages and conductances (for every micotime bin) % csd - spectral density (for every TR) % w - frequencies % % This integration scheme returns a prediction of neuronal responses to % experimental inputs, in terms of BOLD responses and, if requested, local % field potentials and spectral density responses in each region or source. % % The scheme uses a canonical microcircuit nneuron mass model of each % region to evaluate the new fixed point of neuronal activity every time % the input changes. This is evaluated in microtime (usually a 16th of the % TR). These neuronal states are then used to compute the pre-synaptic % activity of (extrinsic and intrinsic) afferents to each subpopulation to % furnish a neurovascular signal. The ensuing haemodynamic response is then % estimated by integrating a haemodynamic model. Neurovascular coupling % depends upon the mixtures of pre-synaptic activity driving haemodynamic % model. The associated weights are free parameters. %__________________________________________________________________________ % Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging % Karl Friston % $Id: spm_gen_fmri.m 6922 2016-11-02 17:28:23Z karl $ % persistent variables to speed integration schemes %========================================================================== persistent pP pf qf rf try INT = any(spm_vec(pP) - spm_vec(P.N)); catch INT = 1; end pP = P.N; % integrate neural system - when imput changes %========================================================================== if INT || nargout > 1 TOL = exp(-6); % tolerance for fixed point x = spm_vec(M.x.x); u = U.u(1,:) - 1; D = 1; % neuronal model %---------------------------------------------------------------------- N.f = spm_funcheck(M.fn); N.x = M.x.x; N.m = numel(u); f = @M.f; % lead field model %---------------------------------------------------------------------- N.g = @spm_gx_erp; N.l = M.l; N.dipfit.model = 'TFM'; N.dipfit.type = 'LFP'; N.dipfit.Ns = M.l; N.dipfit.Nc = M.l; for t = 1:size(U.u,1) % recompute connectivity parameters if input has changed %------------------------------------------------------------------ if any(u - U.u(t,:)); % input %-------------------------------------------------------------- u = U.u(t,:); % recompute input dependent parameters %-------------------------------------------------------------- Q = P.N; for i = 1:N.m % extrinsic connections %---------------------------------------------------------- B{1} = Q.B{1}(:,:,i); B{2} = Q.B{2}(:,:,i); G{1} = diag(B{1}); G{2} = diag(B{2}); Q.A{1} = Q.A{1} + u(i)*(B{1} - diag(G{1})); Q.A{3} = Q.A{3} + u(i)*(B{2} - diag(G{2})); % intrinsic connections %---------------------------------------------------------- Q.G(:,2) = Q.G(:,2) + u(i)*G{1}; Q.G(:,4) = Q.G(:,4) + u(i)*G{2}; end % Jacobian df/dx, checking for neuronal delay operator %-------------------------------------------------------------- if nargout(N.f) >= 3 [fx,dfdx,D] = N.f(x,u,Q,N); elseif nargout(f) == 2 [fx,dfdx] = N.f(x,u,Q,N); else dfdx = spm_cat(spm_diff(N.f,x,u,Q,N,1)); end dfdx = D*dfdx; % condition unstable eigenmodes %-------------------------------------------------------------- [v,s] = eig(full(dfdx),'nobalance'); s = diag(s); s = 1j*imag(s) + real(s) - exp(real(s)); % dx = (expm(dt*df/dx) - I)*inv(df/dx)*f(x,u) %-------------------------------------------------------------- s = (exp(U.dt*s) - 1)./s; J = real(v*diag(s)*pinv(v)); % reset update %-------------------------------------------------------------- dx = 1; % cross spectral density if required %-------------------------------------------------------------- if nargout > 1 Q = spm_L_priors(N.dipfit,Q); Q = spm_ssr_priors(Q); end if nargout > 2; [g,w] = spm_csd_mtf(Q,N); end end % if neuronal activity is not at its fixed point %------------------------------------------------------------------ if any(abs(dx) > TOL) dx = J*N.f(x,u,Q,N); x = x + dx; [p,q,r] = N.f(x,u,Q,N,'activity'); end % presynaptic neuronal activity at this time point %------------------------------------------------------------------ pf(:,:,t) = p; % intrinsic (inhibitory) input qf(:,:,t) = q; % intrinsic (excitatory) input rf(:,:,t) = r; % extrinsic (excitatory) input % electrophysiological predictions %------------------------------------------------------------------ if nargout > 1 lfp(:,t) = spm_gx_erp(x,u,Q,N); end % induced responses %------------------------------------------------------------------ if nargout > 2 for i = 1:M.l psd(t,:,i) = real(g{1}(:,i,i)); end end end end % spectral responses every TR (with spectral smoothing) %-------------------------------------------------------------------------- if nargout > 2 j = fix(linspace(1,t,M.ns)); for i = 1:M.l for t = 1:M.ns csd(t,:,i) = spm_morlet_conv(psd(j(t),:,i),w,U.dt,16); end end end % neurovascular input in terms of intrinsic and extrinsic afferents %========================================================================== for i = 1:size(pf,1) a(:,i) = squeeze(pf(i,:,:))'*P.J(:,1) + ... squeeze(qf(i,:,:))'*P.J(:,2) + ... squeeze(rf(i,:,:))'*P.J(:,3); end U.u = a; % integrate dynamics and generate prediction %========================================================================== % haemodynamic model %-------------------------------------------------------------------------- H.f = @spm_fx_hdm; H.g = @spm_gx_hdm; H.x = M.x.h; H.m = M.m; H.l = M.l; H.ns = M.ns; % solve for haemodynamic responses %-------------------------------------------------------------------------- y = spm_int(P.H,H,U);