0001 function [r_st,marsD,changef] = mars_spm_graph(marsD,rno,Ic)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 if ~is_mars_estimated(marsD)
0037 error('Need estimated design for plot');
0038 end
0039 if nargin < 2
0040 rno = [];
0041 end
0042 if nargin < 3
0043 Ic = [];
0044 end
0045 changef = 0;
0046
0047
0048 def_r_st = struct(...
0049 'Y', [],...
0050 'y', [],...
0051 'beta', [],...
0052 'SE', [],...
0053 'cbeta',[], ...
0054 'PSTH',[]);
0055 cbeta = []; PSTH = [];
0056
0057
0058 SPM = des_struct(marsD);
0059 xCon = SPM.xCon;
0060
0061
0062 if isempty(rno)
0063 if n_regions(SPM.marsY) > 1
0064 error('Need to specify region number');
0065 end
0066 rno = 1;
0067 end
0068
0069
0070 sY = summary_data(SPM.marsY);
0071 y = apply_filter(marsD, sY(:, rno));
0072
0073
0074 xX = SPM.xX;
0075
0076
0077 XYZstr = region_name(SPM.marsY, rno);
0078 XYZstr = XYZstr{1};
0079
0080
0081
0082
0083
0084
0085 beta = SPM.betas(:, rno);
0086
0087
0088
0089 ResidualMS = SPM.ResidualMS(rno);
0090 Bcov = ResidualMS*SPM.xX.Bcov;
0091
0092
0093
0094 Fgraph = spm_figure('GetWin','Graphics');
0095
0096
0097
0098
0099 spm_results_ui('Clear',Fgraph,2);
0100
0101
0102
0103 if isempty(y)
0104
0105
0106
0107 R = NaN*ones(size(SPM.xX.X,1),1);
0108
0109 else
0110
0111
0112 R = spm_sp('r',SPM.xX.xKXs,y);
0113
0114 end
0115
0116
0117
0118
0119
0120
0121
0122 P05_Z = 1.6449;
0123 CI = P05_Z;
0124
0125
0126
0127 Col = [0 0 0; .8 .8 .8; 1 .5 .5];
0128
0129
0130
0131
0132
0133
0134 Cplot = { 'Contrast estimates and 90% C.I.',...
0135 'Fitted responses',...
0136 'Event-related responses',...
0137 'Parametric responses',...
0138 'Volterra Kernels'};
0139
0140
0141
0142
0143 try
0144 Sess = SPM.Sess;
0145 catch
0146 Cplot = Cplot(1:2);
0147 end
0148 Cplot = Cplot{spm_input('Plot',-1,'m',Cplot)};
0149
0150 switch Cplot
0151
0152
0153
0154 case {'Contrast estimates and 90% C.I.','Fitted responses'}
0155
0156 if isempty(Ic)
0157
0158
0159 [Ic marsD changef] = ui_get_contrasts(...
0160 marsD, 'T|F',1, 'Select contrast...', ' for plot', 1);
0161 if changef, SPM.xCon = get_contrasts(marsD); end
0162 end
0163 TITLE = {Cplot SPM.xCon(Ic).name};
0164
0165
0166
0167 case {'Event-related responses','Parametric responses','Volterra Kernels'}
0168
0169
0170
0171 s = length(Sess);
0172 if s > 1
0173 s = spm_input('which session','+1','n1',1,s);
0174 end
0175
0176
0177
0178 switch Cplot
0179 case 'Volterra Kernels'
0180 u = length(Sess(s).Fc);
0181 otherwise
0182 u = length(Sess(s).U);
0183 end
0184 Uname = {};
0185 for i = 1:u
0186 Uname{i} = Sess(s).Fc(i).name;
0187 end
0188
0189
0190
0191 str = sprintf('which effect');
0192 u = spm_input(str,'+1','m',Uname);
0193
0194
0195
0196 dt = SPM.xBF.dt;
0197
0198 end
0199
0200 switch Cplot
0201
0202
0203
0204 case 'Contrast estimates and 90% C.I.'
0205
0206
0207
0208 cbeta = SPM.xCon(Ic).c'*beta;
0209 CI = CI*sqrt(diag(SPM.xCon(Ic).c'*Bcov*SPM.xCon(Ic).c));
0210
0211
0212
0213 figure(Fgraph)
0214 subplot(2,1,2)
0215 cla
0216 hold on
0217
0218
0219
0220 h = bar(cbeta);
0221 set(h,'FaceColor',Col(2,:))
0222
0223
0224
0225 for j = 1:length(cbeta)
0226 line([j j],([CI(j) 0 - CI(j)] + cbeta(j)),...
0227 'LineWidth',6,'Color',Col(3,:))
0228 end
0229
0230 title(TITLE,'FontSize',12)
0231 xlabel('contrast')
0232 ylabel(['contrast estimate',XYZstr])
0233 set(gca,'XLim',[0.4 (length(cbeta) + 0.6)])
0234 hold off
0235
0236
0237
0238 Y = [];
0239
0240
0241
0242 case 'Fitted responses'
0243
0244
0245
0246 str = 'predicted or adjusted response?';
0247 if spm_input(str,'!+1','b',{'predicted','adjusted'},[1 0]);
0248
0249
0250
0251 Y = SPM.xX.X*SPM.xCon(Ic).c*pinv(SPM.xCon(Ic).c)*beta;
0252 else
0253
0254
0255
0256 Y = spm_FcUtil('Yc',SPM.xCon(Ic),SPM.xX.xKXs,beta);
0257
0258 end
0259
0260
0261
0262 y = Y + R;
0263
0264
0265
0266 Xplot = { 'an explanatory variable',...
0267 'scan or time',...
0268 'a user specified ordinate'};
0269 Cx = spm_input('plot against','!+1','m',Xplot);
0270
0271
0272
0273 if Cx == 1
0274
0275 str = 'Which explanatory variable?';
0276 i = spm_input(str,'!+1','m',SPM.xX.name);
0277 x = SPM.xX.xKXs.X(:,i);
0278 XLAB = SPM.xX.name{i};
0279
0280
0281
0282 elseif Cx == 2
0283
0284 if isfield(SPM.xY,'RT')
0285 x = SPM.xY.RT*[1:size(Y,1)]';
0286 XLAB = 'time {seconds}';
0287 else
0288 x = [1:size(Y,1)]';
0289 XLAB = 'scan number';
0290 end
0291
0292
0293
0294 elseif Cx == 3
0295
0296 x = spm_input('enter ordinate','!+1','e','',size(Y,1));
0297 XLAB = 'ordinate';
0298
0299 end
0300
0301
0302
0303 figure(Fgraph)
0304 subplot(2,1,2)
0305 cla
0306 hold on
0307 [p q] = sort(x);
0308 if all(diff(x(q)))
0309 plot(x(q),Y(q),'LineWidth',4,'Color',Col(2,:));
0310 plot(x(q),y(q),':','Color',Col(1,:));
0311 plot(x(q),y(q),'.','MarkerSize',8, 'Color',Col(3,:));
0312
0313 else
0314 plot(x(q),Y(q),'.','MarkerSize',16,'Color',Col(1,:));
0315 plot(x(q),y(q),'.','MarkerSize',8, 'Color',Col(2,:));
0316 xlim = get(gca,'XLim');
0317 xlim = [-1 1]*diff(xlim)/4 + xlim;
0318 set(gca,'XLim',xlim)
0319
0320 end
0321 title(TITLE,'FontSize',12)
0322 xlabel(XLAB)
0323 ylabel(['response',XYZstr])
0324 legend('fitted','plus error')
0325 hold off
0326
0327
0328
0329 case 'Event-related responses'
0330
0331
0332
0333 Rplot = { 'fitted response and PSTH',...
0334 'fitted response and 90% C.I.',...
0335 'fitted response and adjusted data'};
0336
0337 if isempty(y)
0338 TITLE = Rplot{2};
0339 else
0340 TITLE = Rplot{spm_input('plot in terms of','+1','m',Rplot)};
0341 end
0342
0343
0344
0345 switch TITLE
0346 case 'fitted response and PSTH'
0347
0348
0349
0350
0351 str = 'bin size (secs)';
0352 BIN = sprintf('%0.2f',SPM.xY.RT);
0353 BIN = spm_input(str,'!+1','r',BIN);
0354 xBF = SPM.xBF;
0355 U = Sess(s).U(u);
0356 U.u = U.u(:,1);
0357 xBF.name = 'Finite Impulse Response';
0358 xBF.order = round(32/BIN);
0359 xBF.length = xBF.order*BIN;
0360 xBF = pr_spm_get_bf(xBF);
0361 BIN = xBF.length/xBF.order;
0362 X = pr_spm_volterra(U,xBF.bf,1);
0363 k = SPM.nscan(s);
0364 X = X([0:(k - 1)]*SPM.xBF.T + SPM.xBF.T0 + 32,:);
0365
0366
0367
0368 jX = Sess(s).row;
0369 iX = Sess(s).col(Sess(s).Fc(u).i);
0370 iX0 = [1:size(SPM.xX.X,2)];
0371 iX0(iX) = [];
0372 X = [X SPM.xX.X(jX,iX0)];
0373 X = SPM.xX.W(jX,jX)*X;
0374 X = [X SPM.xX.K(s).X0];
0375
0376
0377
0378 j = xBF.order;
0379 xX = spm_sp('Set',X);
0380 pX = spm_sp('x-',xX);
0381 PSTH = pX*y(jX);
0382 res = spm_sp('r',xX,y(jX));
0383 df = size(X,1) - size(X,2);
0384 bcov = pX*pX'*sum(res.^2)/df;
0385 PSTH = PSTH(1:j)/dt;
0386 PST = [1:j]*BIN - BIN/2;
0387 PCI = CI*sqrt(diag(bcov(1:j,(1:j))))/dt;
0388 end
0389
0390
0391
0392 X = SPM.xBF.bf/dt;
0393 x = ([1:size(X,1)] - 1)*dt;
0394 j = Sess(s).col(Sess(s).Fc(u).i(1:size(X,2)));
0395 B = beta(j);
0396
0397
0398
0399 Y = X*B;
0400 CI = CI*sqrt(diag(X*Bcov(j,j)*X'));
0401
0402
0403
0404 pst = Sess(s).U(u).pst;
0405 bin = round(pst/dt);
0406 q = find((bin >= 0) & (bin < size(X,1)));
0407 y = R(Sess(s).row(:));
0408 pst = pst(q);
0409 y = y(q) + Y(bin(q) + 1);
0410
0411
0412
0413 figure(Fgraph)
0414 subplot(2,1,2)
0415 hold on
0416 switch TITLE
0417
0418 case 'fitted response and PSTH'
0419
0420 errorbar(PST,PSTH,PCI)
0421 plot(PST,PSTH,'LineWidth',4,'Color',Col(2,:))
0422 plot(x,Y,'-.','Color',Col(3,:))
0423
0424 case 'fitted response and 90% C.I.'
0425
0426 plot(x,Y,'Color',Col(2,:),'LineWidth',4)
0427 plot(x,Y + CI,'-.',x,Y - CI,'-.','Color',Col(1,:))
0428
0429 case 'fitted response and adjusted data'
0430
0431 plot(x,Y,'Color',Col(2,:),'LineWidth',4)
0432 plot(pst,y,'.','Color',Col(3,:))
0433
0434 end
0435
0436
0437
0438 [i j] = max(Y);
0439 text(ceil(1.1*x(j)),i,Sess(s).Fc(u).name,'FontSize',8);
0440 title(TITLE,'FontSize',12)
0441 xlabel('peristimulus time {secs}')
0442 ylabel(['response',XYZstr])
0443 hold off
0444
0445
0446
0447
0448 case 'Parametric responses'
0449
0450
0451
0452
0453 if ~Sess(s).U(u).P(1).h, return, end
0454
0455
0456
0457 bf = SPM.xBF.bf;
0458 pst = ([1:size(bf,1)] - 1)*dt;
0459
0460
0461
0462 str = 'which parameter';
0463 p = spm_input(str,'+1','m',{Sess(s).U(u).P.name});
0464 P = Sess(s).U(u).P(p).P;
0465 q = [];
0466 for i = 0:Sess(s).U(u).P(p).h;
0467 q = [q spm_en(P).^i];
0468 end
0469 q = spm_orth(q);
0470
0471
0472
0473
0474 j = Sess(s).col(Sess(s).Fc(u).i);
0475 B = beta(j);
0476
0477
0478
0479 Y = zeros(size(bf,1),size(q,1));
0480 uj = Sess(s).U(u).P(p).i;
0481 for i = 1:size(P,1)
0482 U = sparse(1,uj,q(i,:),1,size(Sess(s).U(u).u,2));
0483 X = kron(U,bf);
0484 Y(:,i) = X*B;
0485 end
0486 [P j] = sort(P);
0487 Y = Y(:,j);
0488
0489
0490
0491 figure(Fgraph)
0492 subplot(2,2,3)
0493 surf(pst,P,Y')
0494 shading flat
0495 title(Sess(s).U(u).name{1},'FontSize',12)
0496 xlabel('PST {secs}')
0497 ylabel(Sess(s).U(u).P(p).name)
0498 zlabel(['responses',XYZstr])
0499 axis square
0500
0501
0502
0503 subplot(2,2,4)
0504 [j i] = max(mean(Y,2));
0505 plot(P,Y(i,:),'LineWidth',4,'Color',Col(2,:))
0506 str = sprintf('response at %0.1fs',i*dt);
0507 title(str,'FontSize',12)
0508 xlabel(Sess(s).U(u).P(p).name)
0509 axis square
0510 grid on
0511
0512
0513
0514
0515 case 'Volterra Kernels'
0516
0517
0518
0519 bf = SPM.xBF.bf/dt;
0520 pst = ([1:size(bf,1)] - 1)*dt;
0521
0522
0523
0524 if u > length(Sess(s).U)
0525
0526
0527
0528 j = Sess(s).col(Sess(s).Fc(u).i);
0529 B = beta(j);
0530 i = 1;
0531 Y = 0;
0532 for p = 1:size(bf,2)
0533 for q = 1:size(bf,2)
0534 Y = Y + B(i)*bf(:,p)*bf(:,q)';
0535 i = i + 1;
0536 end
0537 end
0538
0539
0540
0541 figure(Fgraph)
0542 subplot(2,2,3)
0543 imagesc(pst,pst,Y)
0544 axis xy
0545 axis image
0546
0547 title('2nd order Kernel','FontSize',12);
0548 xlabel('perstimulus time {secs}')
0549 ylabel('perstimulus time {secs}')
0550
0551 subplot(2,2,4)
0552 plot(pst,Y)
0553 axis square
0554 grid on
0555
0556 title(Sess(s).Fc(u).name,'FontSize',12);
0557 xlabel('perstimulus time {secs}')
0558
0559
0560
0561
0562 else
0563 j = Sess(s).col(Sess(s).Fc(u).i(1:size(bf,2)));
0564 B = beta(j);
0565 Y = bf*B;
0566
0567
0568
0569 figure(Fgraph)
0570 subplot(2,1,2)
0571 plot(pst,Y)
0572 grid on
0573 axis square
0574
0575 title({'1st order Volterra Kernel' Sess(s).Fc(u).name},...
0576 'FontSize',12);
0577 xlabel('perstimulus time {secs}')
0578 ylabel(['impluse response',XYZstr])
0579 end
0580
0581 end
0582
0583
0584
0585
0586 spm_results_ui('PlotUi',gca)
0587
0588
0589 r_st = mars_struct('fillafromb', def_r_st, struct(...
0590 'Y', Y, 'y', y, 'beta', beta, 'Bcov', Bcov, ...
0591 'cbeta', cbeta, 'PSTH', PSTH));