spm_vb_logbf.m 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. function [xCon,SPM] = spm_vb_logbf(SPM,XYZ,xCon,ic)
  2. % Compute and write log Bayes factor image
  3. % FORMAT [xCon,SPM] = spm_vb_logbf(SPM,XYZ,xCon,ic)
  4. %
  5. % SPM - SPM data structure
  6. % XYZ - voxel list
  7. % xCon - contrast info
  8. % ic - contrast number
  9. %__________________________________________________________________________
  10. % Copyright (C) 2012-2014 Wellcome Trust Centre for Neuroimaging
  11. % Will Penny
  12. % $Id: spm_vb_logbf.m 6079 2014-06-30 18:25:37Z spm $
  13. % Get approximate posterior covariance using Taylor-series approximation
  14. %-Get number of sessions
  15. %--------------------------------------------------------------------------
  16. nsess = length(SPM.nscan); %length(SPM.Sess);
  17. %-Compound Contrast
  18. %--------------------------------------------------------------------------
  19. c = xCon(ic).c;
  20. kc = size(c,2);
  21. %-Get posterior beta's
  22. %--------------------------------------------------------------------------
  23. Nk = size(SPM.xX.X,2);
  24. for k=1:Nk
  25. beta(k,:) = spm_get_data(SPM.VCbeta(k),XYZ);
  26. end
  27. %-Get posterior SD beta's
  28. %--------------------------------------------------------------------------
  29. Nk = size(SPM.xX.X,2);
  30. for k=1:Nk
  31. sd_beta(k,:) = spm_get_data(SPM.VPsd(k),XYZ);
  32. end
  33. %-Get AR coefficients
  34. %--------------------------------------------------------------------------
  35. for s=1:nsess
  36. for p=1:SPM.PPM.AR_P
  37. Sess(s).a(p,:) = spm_get_data(SPM.PPM.Sess(s).VAR(p),XYZ);
  38. end
  39. end
  40. %-Get noise SD
  41. %--------------------------------------------------------------------------
  42. for s=1:nsess
  43. Sess(s).lambda = spm_get_data(SPM.PPM.Sess(s).VHp,XYZ);
  44. end
  45. %-Loop over voxels
  46. %=======================================================================
  47. Nvoxels = size(XYZ,2);
  48. D = NaN(reshape(SPM.xVol.DIM(1:3),1,[]));
  49. spm_progress_bar('Init',100,'Estimating Bayes factor','');
  50. for v=1:Nvoxels
  51. %-Which block are we in ?
  52. %----------------------------------------------------------------------
  53. block_index = SPM.xVol.labels(1,v);
  54. V = zeros(kc,kc);
  55. m = zeros(kc,1);
  56. logbf = 0;
  57. for s=1:nsess
  58. %-Reconstruct approximation to voxel wise correlation matrix
  59. %------------------------------------------------------------------
  60. R = SPM.PPM.Sess(s).block(block_index).mean.R;
  61. if SPM.PPM.AR_P > 0
  62. dh = Sess(s).a(:,v)'-SPM.PPM.Sess(s).block(block_index).mean.a;
  63. dh = [dh Sess(s).lambda(v)-SPM.PPM.Sess(s).block(block_index).mean.lambda];
  64. for i=1:length(dh)
  65. R = R + SPM.PPM.Sess(s).block(block_index).mean.dR(:,:,i) * dh(i);
  66. end
  67. end
  68. %-Get indexes of regressors specific to this session
  69. %------------------------------------------------------------------
  70. scol = SPM.Sess(s).col;
  71. mean_col_index = SPM.Sess(nsess).col(end) + s;
  72. scol = [scol mean_col_index];
  73. %-Reconstruct approximation to voxel wise covariance matrix
  74. %------------------------------------------------------------------
  75. Sigma_post = (sd_beta(scol,v) * sd_beta(scol,v)') .* R;
  76. %-Get component of contrast covariance specific to this session
  77. %------------------------------------------------------------------
  78. CC = c(scol,:);
  79. %-Get posterior mean contrast vector
  80. %------------------------------------------------------------------
  81. post_mean = CC' * beta(scol,v);
  82. post_cov = CC' * Sigma_post * CC;
  83. prior_mean = zeros(kc,1);
  84. prior_cov = CC'*diag(1./SPM.PPM.Sess(s).block(block_index).mean_alpha)*CC;
  85. a = zeros(kc,1);
  86. en = a - post_mean;
  87. iC = inv(post_cov);
  88. logbf = logbf - 0.5*spm_logdet(prior_cov)+0.5*spm_logdet(post_cov)+0.5*en'*iC*en;
  89. end
  90. D(XYZ(1,v),XYZ(2,v),XYZ(3,v)) = logbf;
  91. if rem(v,100)==0
  92. % update progress bar every 100th voxel
  93. spm_progress_bar('Set',100*v/Nvoxels);
  94. end
  95. end
  96. xCon(ic).eidf = rank(post_cov);
  97. spm_progress_bar('Clear');
  98. %-Create handle
  99. %--------------------------------------------------------------------------
  100. Vhandle = struct(...
  101. 'fname', sprintf(['logbf_%04d' spm_file_ext],ic),...
  102. 'dim', SPM.xVol.DIM',...
  103. 'dt', [spm_type('float32') spm_platform('bigend')],...
  104. 'mat', SPM.xVol.M,...
  105. 'pinfo', [1,0,0]',...
  106. 'descrip',sprintf('Log Bayes factor con %d: %s',ic,xCon(ic).name));
  107. %-Write image
  108. %--------------------------------------------------------------------------
  109. Vhandle = spm_create_vol(Vhandle);
  110. Vhandle = spm_write_vol(Vhandle,D);
  111. xCon(ic).Vcon = Vhandle;
  112. fprintf('%s%30s\n',repmat(sprintf('\b'),1,30),...
  113. sprintf('...written %s',spm_file(Vhandle.fname,'filename'))); %-#