spm_DesRep.m 55 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578
  1. function varargout = spm_DesRep(varargin)
  2. % Design reporting utilities
  3. % FORMAT varargout = spm_DesRep(action,varargin)
  4. %
  5. % spm_DesRep (design reporting) is a suite of utility functions for various
  6. % graphical reports on a given experimental design, embodied in the design
  7. % matrix structure and other associated data structures.
  8. % For detailed programmers comments, see format specifications in main body
  9. % of code.
  10. %
  11. % ----------------
  12. %
  13. % By default, spm_DesRep prompts for selection of a SPM.mat file.
  14. %
  15. % Given details of a design spm_DesRep sets up a "Design" menu in the
  16. % SPM 'Interactive' window. The menu options launch various graphical
  17. % summaries of the current SPM design in the SPM 'Graphics' window.
  18. %
  19. % * Design Matrix - Displays graphical summary of the design matrix
  20. %
  21. % The design is labelled with the corresponding parameter and
  22. % file names, and is displayed as an image scaled (using
  23. % spm_DesMtx('sca',...) such that zero is mid-grey, -1 is black, and +1
  24. % is white. Covariates exceeding this randge are scaled to fit.
  25. %
  26. % The design matrix is "surfable": Clicking (and holding or dragging)
  27. % around the design matrix image reports the corresponding value of the
  28. % design matrix ('normal' click - "left" mouse button usually), the
  29. % image filename ('extend' mouse click - "middle" mouse), or parameter
  30. % name ('alt' click - "right" mouse). Double clicking the design matrix
  31. % image extracts the design matrix into the base MATLAB workspace.
  32. %
  33. % Under the design matrix the parameter estimability is displayed as a
  34. % 1xp matrix of grey and white squares. Parameters that are not
  35. % uniquely specified by the model are shown with a grey patch. Surfing
  36. % the estimability image reports the parameter names and their
  37. % estimability. Double clicking extracts the estimability vector into
  38. % the base MATLAB workspace.
  39. %
  40. % * Design orthogonality - Displays orthogonality matrix for this design
  41. %
  42. % The design matrix is displayed as in "Design Matrix" view above,
  43. % labelled with the parameter names.
  44. %
  45. % Under the design matrix the design orthogonality matrix is
  46. % displayed. For each pair of columns of the design matrix, the
  47. % orthogonality matrix depicts the magnitude of the cosine of the
  48. % angle between them, with the range 0 to 1 mapped to white to
  49. % black. Orthogonal vectors (shown in white), have cosine of zero.
  50. % Colinear vectors (shown in black), have cosine of 1 or -1.
  51. %
  52. % The cosine of the angle between two vectors a & b is obtained by
  53. % dividing the dot product of the two vectors by the product of
  54. % their lengths:
  55. %
  56. % a'*b
  57. % ------------------------
  58. % sqrt(sum(a.^2)*sum(b.^2)
  59. %
  60. % If (and only if) both vectors have zero mean, i.e.
  61. % sum(a)==sum(b)==0, then the cosine of the angle between the
  62. % vectors is the same as the correlation between the two variates.
  63. %
  64. % The design orthogonality matrix is "surfable": Clicking (and
  65. % holding or dragging) the cursor around the design orthogonality
  66. % image reports the orthogonality of the correponding pair of
  67. % columns. Double clicking on the orthogonality matrix extracts
  68. % the contrast orthogonality matrix into the base MATLAB
  69. % workspace.
  70. %
  71. % * Explore design - Sub-menu's for detailed design exploration.
  72. %
  73. % If this is an fMRI design, then the session & trial/condition
  74. % structure of the design is reflected in the sub-menu structure.
  75. % Selecting a given session, and then trial/condition within the
  76. % session, launches a comprehensive display of the parameters of
  77. % that design.
  78. %
  79. % If not an fMRI design, then the Explore sub-menu has two options:
  80. % "Files and factors" & "Covariates".
  81. %
  82. % * Explore: Files and factors - Multi-page listing of filenames,
  83. % factor indicies and covariates.
  84. %
  85. % The covariates printed are the raw covariates as entered into
  86. % SPM, with the exception of the global value, which is printed
  87. % after any grand mean scaling.
  88. %
  89. % * Explore: Covariates - Plots of the covariates, showing how they are
  90. % included into the model.
  91. %
  92. % Covariates are plotted, one per page, overlaid on the design
  93. % matrix. The description strings in the xC covariate structure
  94. % array are displayed. The corresponding design matrix column(s)
  95. % is(are) highlighted.
  96. %
  97. % * Clear - clears Graphics window, re-instating Results section MIP
  98. % & design matrix graphics (if in the results section).
  99. % * Help - displays this text!
  100. %
  101. % ----------------
  102. %
  103. % spm_DesRep also handles "surfing" of contrast depictions, which are
  104. % bar-graphs for T-contrasts and images for F-contrasts. Clicking
  105. % ('normal' click - "left" mouse button usually) with the on the bars
  106. % of the bar-graphs, or anywhere in an image, and dragging, dynamically
  107. % reports the contrast weight depicted under the cursor. The format of
  108. % the report string is:
  109. % #{T/F}: <name> (ij) = <weight>
  110. % ...where # is the contrast number, T/F indicates the type of contrast,
  111. % <name> the name given to the contrast, ij the index into the contrast
  112. % vector/matrix weight under the cursor, and <weight> the corresponding
  113. % contrast weight.
  114. %
  115. % Double clicking on a contrast depiction extracts the contrast weights
  116. % into the base workspace.
  117. %__________________________________________________________________________
  118. % Copyright (C) 1999-2015 Wellcome Trust Centre for Neuroimaging
  119. % Andrew Holmes
  120. % $Id: spm_DesRep.m 6351 2015-02-26 16:37:18Z guillaume $
  121. %==========================================================================
  122. % - FORMAT specifications for embedded functions
  123. %==========================================================================
  124. %( This is a multi function function, the first argument is an action )
  125. %( string, specifying the particular action function to take. )
  126. %
  127. % FORMAT h = spm_DesRep('DesRepUI',SPM)
  128. % Setup "design" menu for design reporting.
  129. % SPM - structure containing design details. Required fields are:
  130. %
  131. % .xX - design matrix structure
  132. % (See spm_fmri_spm_ui.m & spm_spm.m for formats)
  133. % .xY.P - (char or cellstr) array of filenames
  134. % .xY.VY - array of file handles (from spm_fmri_spm_ui.m)
  135. % .xM - Masking structure
  136. % .xC - Covariate definition structure (not fMRI)
  137. % (see spm_spm_ui.m for format)
  138. % .Sess - fMRI session structure (not needed if not fMRI)
  139. % (see spm_fmri_spm_ui.m for format)
  140. % .xsDes - Design description structure
  141. % (see spm_fmri_spm_ui.m for details)
  142. % .swd - SPM working directory - directory where configuration file resides
  143. % [defaults to empty]
  144. % .SPMid - (recommended) ID string of creator program.
  145. % h - handle of menu created ('Tag'ged as 'DesRepUI')
  146. %
  147. %
  148. % FORMAT spm_DesRep('Files&Factors',P,I,xC,sF,xs)
  149. % Produces multi-page listing of files, factor indices, and covariates.
  150. % P - nxv CellStr of filenames (i.e. reshape(cellstr(SPM.xY.P),size(V)))
  151. % I - nx4 matrix of factor indices
  152. % xC - Covariate structure array (see spm_spm_ui.m for definitions)
  153. % ('rc' & 'cname' fields used)
  154. % sF - 1x4 CellStr of factor names (i.e. D.sF of spm_spm_ui)
  155. % xs - [optional] structure of extra strings containing descriptive
  156. % information which is printed out after the files & variables listing.
  157. % The field names are used as sub-headings, the field values (which
  158. % must be strings or CellStr) printed alongside.
  159. %
  160. % FORMAT spm_DesRep('DesMtx',xX,fnames,xs)
  161. % Produces a one-page graphical summary of the design matrix
  162. % FORMAT spm_DesRep('DesOrth',xX)
  163. % Produces a one-page graphical summary of the design orthogonality
  164. % xX - Structure containing design matrix information
  165. % - the first of {xX.nX, xX.xKXs.X, xX.X} is used for display
  166. % .nX - Desgin matrix already scaled for display
  167. % .xKXs.X - temporally filtered design matrix (within space structure)
  168. % .X - "raw" design matrix (as setup by spm_fmri_spm_ui)
  169. % .name - [optional] px1 CellStr of parameter names
  170. % fnames - [optional] nxv CellStr of filenames (i.e. reshape(cellstr(SPM.xY.P),size(V)))
  171. % xs - [optional] structure of extra strings containing descriptive
  172. % information which is printed at the foot of the page ('DesMtx' usage)
  173. % The field names are used as sub-headings, the field values
  174. % (which must be strings or CellStr) printed alongside.
  175. %
  176. % FORMAT spm_DesRep('fMRIDesMtx',SPM,s,i)
  177. % Interactive review of fMRI design matrix.
  178. % Sess(s).U(i) - see spm_fMRI_design for session s, trial i
  179. %
  180. % FORMAT spm_DesRep('Covs',xC,X,Xnames)
  181. % Plots the covariates and describes how they are included into the model.
  182. % xC - Covariate structure array (see spm_spm_ui.m for details)
  183. % ('rcname','rc','descrip','cname' & 'cols' fields used)
  184. % X - nxp Design matrix
  185. % Xnames - px1 CellStr of parameter names
  186. %
  187. % =========================================================================
  188. % Utility functions and CallBack handlers:
  189. %
  190. % FORMAT s = spm_DesRep('ScanTick',nScan,lim)
  191. % Pares down 1:nScan to at most lim items, showing every 2nd/3rd/... as
  192. % necessary to pair down to <lim items. Always ends with nScan so
  193. % #images is indicated.
  194. % nScan - number of scans
  195. % lim - limit to number of elements of s
  196. % s - 1:nScan pared down accordingly
  197. %
  198. % FORMAT spm_DesRep('SurfDesMtx_CB')
  199. % 'ButtonDownFcn' CallBack for surfing clickable design matrix images
  200. % FORMAT spm_DesRep('SurfDesMtxMo_CB')
  201. % 'WindowButtonMotionFcn' CallBack for surfing clickable design matrix images
  202. % FORMAT spm_DesRep('SurfDesMtxUp_CB')
  203. % 'ButtonUpFcn' CallBack for ending surfing of design matrix images
  204. %
  205. % The design matrix, parameter names and image file names should be
  206. % saved in the UserData of the image object as a structure with fields
  207. % 'X','Xnames' & 'fnames' respectively. The code is robust to any of
  208. % these being empty or mis-specified - surfing simply reports "no
  209. % cached data".
  210. %
  211. % FORMAT spm_DesRep('SurfEstIm_CB')
  212. % 'ButtonDownFcn' CallBack for surfing clickable parameter estimability images
  213. % FORMAT spm_DesRep('SurfEstImMo_CB')
  214. % 'WindowButtonMotionFcn' CallBack for surfing parameter estimability images
  215. % FORMAT spm_DesRep('SurfEstImUp_CB')
  216. % 'ButtonUpFcn' CallBack for ending surfing of parameter estimability images
  217. %
  218. % The binary parameter estimability matrix and parameter names should
  219. % be saved in the UserData of the image object as a structure with
  220. % fields 'est' & 'Xnames' respectively. The code is robust to any of
  221. % these being empty or mis-specified - surfing simply reports "no
  222. % cached data".
  223. %
  224. % FORMAT spm_DesRep('SurfDesO_CB')
  225. % 'ButtonDownFcn' CallBack for surfing clickable design orthogonality images
  226. % FORMAT spm_DesRep('SurfDesOMo_CB')
  227. % 'WindowButtonMotionFcn' CallBack for surfing design orthogonality images
  228. % FORMAT spm_DesRep('SurfDesOUp_CB')
  229. % 'ButtonUpFcn' CallBack for ending surfing of design orthogonality images
  230. %
  231. % The design orthogonality matrix (cosine of angle between vectors),
  232. % correlation index matrix (1 when both columns have zero mean, when
  233. % cos(\theta) equals the correlation), and parameter names should be
  234. % saved in the UserData of the image object as a structure with fields
  235. % 'O', 'bC' & 'Xnames' respectively.
  236. %
  237. % FORMAT spm_DesRep('SurfCon_CB')
  238. % 'ButtonDownFcn' CallBack for surfing clickable contrast depictions
  239. % FORMAT spm_DesRep('SurfConOMo_CB')
  240. % 'WindowButtonMotionFcn' CallBack for surfing contrast depictions
  241. % FORMAT spm_DesRep('SurfConOUp_CB')
  242. % 'ButtonUpFcn' CallBack for ending surfing of contrast depictions
  243. %
  244. % The contrast number, handle of text object to use for reporting and
  245. % contrast structure (for this contrast) should be saved in the UserData
  246. % of the image object as a structure with fields 'i', 'h' & 'xCon'
  247. % respectively.
  248. %__________________________________________________________________________
  249. SVNid = '$Rev: 6351 $';
  250. %-Format arguments
  251. %--------------------------------------------------------------------------
  252. if ~nargin
  253. SPMid = spm('FnBanner',mfilename,SVNid);
  254. hC = spm_DesRep('DesRepUI');
  255. SPM = get(hC,'UserData');
  256. if ~isempty(SPM)
  257. cb_menu([],[],'DesMtx',SPM);
  258. drawnow;
  259. end
  260. return;
  261. end
  262. switch lower(varargin{1})
  263. %==========================================================================
  264. case 'desrepui' %-Design reporting UI
  265. %==========================================================================
  266. % h = spm_DesRep('DesRepUI')
  267. % h = spm_DesRep('DesRepUI',SPM)
  268. %-Load design data from file if not passed as argument
  269. %--------------------------------------------------------------------------
  270. if nargin < 2
  271. [spmmatfile, sts] = spm_select(1,'^SPM\.mat$','Select SPM.mat');
  272. if ~sts, varargout = {[]}; return; end
  273. swd = spm_file(spmmatfile,'fpath');
  274. try
  275. load(fullfile(swd,'SPM.mat'));
  276. catch
  277. error(['Cannot read ' fullfile(swd,'SPM.mat')]);
  278. end
  279. SPM.swd = swd;
  280. else
  281. SPM = varargin{2};
  282. end
  283. %-Canonicalise data
  284. %--------------------------------------------------------------------------
  285. %-Work out where design configuration has come from
  286. if ~isfield(SPM,'cfg')
  287. if isfield(SPM.xX,'V'), cfg = 'SPMest';
  288. elseif isfield(SPM.xY,'VY'), cfg = 'SPMdata';
  289. elseif isfield(SPM,'Sess'), cfg = 'SPMcfg';
  290. else error('Can''t fathom origin!')
  291. end
  292. SPM.cfg = cfg;
  293. end
  294. %-Work out what modality this is
  295. %--------------------------------------------------------------------------
  296. try
  297. SPM.Sess(1);
  298. SPM.modality = 'fMRI';
  299. catch
  300. try
  301. SPM.xC;
  302. catch
  303. SPM.xC = {};
  304. end
  305. SPM.modality = 'PET';
  306. end
  307. %-Add a scaled design matrix to the design data structure
  308. %--------------------------------------------------------------------------
  309. if ~isfield(SPM.xX,'nKX')
  310. SPM.xX.nKX = spm_DesMtx('Sca',SPM.xX.X,SPM.xX.name);
  311. end
  312. %-Draw menu
  313. %==========================================================================
  314. %-Get Interactive window and delete any previous DesRepUI menu
  315. %--------------------------------------------------------------------------
  316. Finter = spm_figure('GetWin','Interactive');
  317. delete(findobj(get(Finter,'Children'),'flat','Tag','DesRepUI'))
  318. %-Draw top level menu
  319. %--------------------------------------------------------------------------
  320. hC = uimenu(Finter,'Label','Design',...
  321. 'Separator','on',...
  322. 'Tag','DesRepUI',...
  323. 'UserData',SPM,...
  324. 'HandleVisibility','on');
  325. %-DesMtx
  326. %--------------------------------------------------------------------------
  327. hDesMtx = uimenu(hC,'Label','Design Matrix','Accelerator','D',...
  328. 'CallBack',{@cb_menu,'DesMtx',SPM},...
  329. 'UserData',hC,...
  330. 'HandleVisibility','off');
  331. %-Design matrix orthogonality
  332. %--------------------------------------------------------------------------
  333. h = uimenu(hC,'Label','Design orthogonality','Accelerator','O',...
  334. 'CallBack',{@cb_menu,'DesOrth',SPM},...
  335. 'UserData',hC,...
  336. 'HandleVisibility','off');
  337. %-Explore design
  338. %--------------------------------------------------------------------------
  339. hExplore = uimenu(hC,'Label','Explore','HandleVisibility','off');
  340. switch SPM.modality
  341. case 'PET'
  342. hFnF = uimenu(hExplore,'Label','Files and factors','Accelerator','F',...
  343. 'CallBack',{@cb_menu,'Files&Factors',SPM},...
  344. 'UserData',hC,...
  345. 'HandleVisibility','off');
  346. hCovs = uimenu(hExplore,'Label','Covariates','Accelerator','C',...
  347. 'CallBack',{@cb_menu,'Covs',SPM},...
  348. 'UserData',hC,...
  349. 'HandleVisibility','off');
  350. if isempty(SPM.xC), set(hCovs,'Enable','off'), end
  351. case 'fMRI'
  352. for j = 1:length(SPM.Sess)
  353. h = uimenu(hExplore,'Label',sprintf('Session %.0f ',j),...
  354. 'HandleVisibility','off');
  355. for k = 1:length(SPM.Sess(j).Fc)
  356. uimenu(h,'Label',SPM.Sess(j).Fc(k).name,...
  357. 'CallBack',{@cb_menu,'fMRIDesMtx',SPM,j,k},...
  358. 'UserData',hC,...
  359. 'HandleVisibility','off')
  360. end
  361. end
  362. end
  363. hxvi = uimenu(hExplore, 'Label','Covariance structure', ...
  364. 'Callback',{@cb_menu,'xVi',SPM},...
  365. 'UserData',hC, 'HandleVisibility','off');
  366. if ~isfield(SPM,'xVi') || (isfield(SPM.xVi,'iid') && SPM.xVi.iid) || ...
  367. ~(isfield(SPM.xVi,'V') || isfield(SPM.xVi,'Vi'))
  368. set(hxvi,'Enable','off');
  369. end
  370. %-Clear, Quit
  371. %--------------------------------------------------------------------------
  372. uimenu(hC,'Label','Clear','Accelerator','L','Separator','on',...
  373. 'CallBack','spm_results_ui(''Clear'')',...
  374. 'HandleVisibility','off');
  375. uimenu(hC,'Label','Quit','Accelerator','Q','Separator','on',...
  376. 'CallBack','spm_results_ui(''Close'');',...
  377. 'HandleVisibility','off');
  378. %-Pop open 'Interactive' window
  379. %--------------------------------------------------------------------------
  380. figure(Finter)
  381. %-Return handle of menu
  382. %--------------------------------------------------------------------------
  383. varargout = {hC};
  384. %==========================================================================
  385. case 'files&factors' %-Summarise files & factors
  386. %==========================================================================
  387. % spm_DesRep('Files&Factors',fnames,I,xC,sF,xs)
  388. if nargin<4, error('insufficient arguments'), end
  389. fnames = varargin{2};
  390. I = varargin{3};
  391. xC = varargin{4};
  392. sF = varargin{5};
  393. if nargin<6, xs=[]; else xs = varargin{6}; end %-Structure of strings
  394. [fnames,CPath] = spm_str_manip(fnames,'c'); %-extract common path component
  395. nScan = size(I,1); %-#images
  396. bL = any(diff(I,1),1); %-Multiple factor levels?
  397. for i=(numel(sF)+1):size(I,2)
  398. sF{i} = sprintf('sF%d',i); %-If more factors than expected
  399. end
  400. %-Get Graphics window & window scaling
  401. Fgraph = spm_figure('GetWin','Graphics');
  402. spm_results_ui('Clear',Fgraph,0)
  403. FS = spm('FontSizes');
  404. %-Display header information
  405. %--------------------------------------------------------------------------
  406. hTax = axes('Position',[0.03,0.85,0.94,0.1],...
  407. 'DefaultTextFontSize',FS(9),...
  408. 'XLim',[0,1],'YLim',[0,1],...
  409. 'Visible','off');
  410. text(0.5,1,'Statistical analysis: Image files & covariates...',...
  411. 'Fontsize',FS(14),'Fontweight','Bold',...
  412. 'HorizontalAlignment','center');
  413. dx1 = 0.05;
  414. dx2 = 0.08;
  415. x = 0; text(x+.02,.1,'image #','Rotation',90);
  416. for i=numel(bL):-1:1
  417. if bL(i), x=x+dx1; text(x+.01,.1,sF{i},'Rotation',90); end
  418. end
  419. for j = 1:length(xC)
  420. n = size(xC(j).rc,2);
  421. if n>1, tmp=xC(j).cname; else tmp={xC(j).rcname}; end
  422. for k=1:n
  423. x=x+dx2;
  424. text(x,.1,tmp{k},'Rotation',90,'Interpreter','TeX');
  425. end
  426. end
  427. x = x + dx2;
  428. text(x,0.65,'Base directory:','FontWeight','Bold');
  429. text(x,0.5,CPath,'FontSize',FS(8));
  430. text(x,0.2,'filename tails...');
  431. line('XData',[0 1],'YData',[0 0],'LineWidth',3,'Color','r');
  432. %-Tabulate file & covariate information
  433. %--------------------------------------------------------------------------
  434. hAx = axes('Position',[0.03,0.05,0.94,0.8],...
  435. 'DefaultTextFontSize',FS(8),...
  436. 'Units','points',...
  437. 'Visible','off');
  438. AxPos = get(hAx,'Position'); set(hAx,'YLim',[0,AxPos(4)])
  439. dy = FS(9); y0 = floor(AxPos(4)) -dy; y = y0;
  440. for i = 1:nScan
  441. %-Scan indices
  442. x = 0; text(x,y,sprintf('%03d',i));
  443. for j=numel(bL):-1:1
  444. if bL(j), x=x+dx1; text(x,y,sprintf('%02d',I(i,j))); end
  445. end
  446. %-Covariates
  447. for j = 1:length(xC)
  448. for k=1:size(xC(j).rc,2)
  449. x=x+dx2;
  450. text(x,y,sprintf('%6g',xC(j).rc(i,k)),...
  451. 'HorizontalAlignment','Center');
  452. end
  453. end
  454. %-Filename tail(s) - could be multivariate
  455. x=x+dx2;
  456. text(x,y,fnames{i});
  457. y=y-dy;
  458. %-Paginate if necessary
  459. if y<dy
  460. text(0.5,0,sprintf('Page %d',spm_figure('#page')),...
  461. 'FontSize',FS(8),'FontAngle','italic');
  462. spm_figure('NewPage',[hAx;get(hAx,'Children')])
  463. hAx = axes('Units','points','Position',AxPos,...
  464. 'DefaultTextFontSize',FS(8),'YLim',[0,AxPos(4)],...
  465. 'Visible','off');
  466. y = y0;
  467. text(y,0,'continued...','FontAngle','Italic');
  468. end
  469. end
  470. line('XData',[0 1],'YData',[y y],'LineWidth',3,'Color','r');
  471. %-Display description strings at bottom of current page
  472. %--------------------------------------------------------------------------
  473. if ~isempty(xs)
  474. y = y - 2*dy;
  475. for sf = fieldnames(xs)'
  476. text(0.3,y,[strrep(sf{1},'_',' '),' :'],...
  477. 'HorizontalAlignment','Right','FontWeight','Bold',...
  478. 'FontSize',FS(9));
  479. s = xs.(sf{1});
  480. if ~iscellstr(s), s={s}; end
  481. for i=1:numel(s)
  482. text(0.31,y,s{i},'FontSize',FS(9));
  483. y = y - dy;
  484. end
  485. end
  486. end
  487. %-Register last page if paginated
  488. if spm_figure('#page')>1
  489. text(0.5,0,sprintf('Page %d/%d',spm_figure('#page')*[1,1]),...
  490. 'FontSize',FS(8),'FontAngle','italic');
  491. spm_figure('NewPage',[hAx;get(hAx,'Children')]);
  492. end
  493. %-Pop up the Graphics window
  494. %--------------------------------------------------------------------------
  495. figure(Fgraph)
  496. %==========================================================================
  497. case 'xvi'
  498. %==========================================================================
  499. % spm_DesRep('xVi',xVi)
  500. if nargin<2, error('insufficient arguments'), end
  501. if ~isstruct(varargin{2}), error('covariance matrix structure required'), end
  502. %-Display
  503. %==========================================================================
  504. %-Get graphics window & FontSizes
  505. %--------------------------------------------------------------------------
  506. Fgraph = spm_figure('GetWin','Graphics');
  507. spm_results_ui('Clear',Fgraph,0)
  508. FS = spm('FontSizes');
  509. %-Title
  510. %--------------------------------------------------------------------------
  511. hTax = axes('Position',[0.03,0,0.94,1],...
  512. 'DefaultTextFontSize',FS(9),...
  513. 'XLim',[0,1],'YLim',[0,1],...
  514. 'Visible','off');
  515. str = 'Statistical analysis: Covariance structure';
  516. text(0.5,0.95,str,'Fontsize',FS(14),'Fontweight','Bold',...
  517. 'HorizontalAlignment','center');
  518. line('Parent',hTax,...
  519. 'XData',[0.3 0.7],'YData',[0.92 0.92],'LineWidth',3,'Color','r');
  520. %-Display covariance matrix
  521. %--------------------------------------------------------------------------
  522. hCovMtx(1) = axes('Position',[.07 .4 .6 .4]);
  523. hCovMtxSc = [];
  524. if isfield(varargin{2},'V')
  525. clim = full([-max(varargin{2}.V(:))/2 max(varargin{2}.V(:))]); % scale 0 to gray
  526. hCovMtxIm(1) = imagesc(varargin{2}.V, clim);
  527. hCovMtxSc = colorbar;
  528. set(hCovMtxSc,'Ylim',[0 clim(2)]); % cut colorbar at 0
  529. %-Setup callbacks to allow interrogation of covariance matrix
  530. %------------------------------------------------------------------------
  531. set(hCovMtxIm(1),'UserData',...
  532. varargin{2})
  533. set(hCovMtxIm(1),'ButtonDownFcn','spm_DesRep(''SurfxVi_CB'')')
  534. if isfield(varargin{2},'form')
  535. str = sprintf('Covariance structure V: %s',varargin{2}.form);
  536. else
  537. str = 'Covariance structure V';
  538. end
  539. if isfield(varargin{2},'var') && isfield(varargin{2},'dep') && ...
  540. isfield(varargin{2},'sF') && isfield(varargin{2},'I')
  541. r = find((max(varargin{2}.I) > 1) & ~varargin{2}.var & ~varargin{2}.dep);
  542. if any(varargin{2}.dep)
  543. cmstr = 'yes';
  544. else
  545. cmstr = 'no';
  546. end
  547. str = sprintf(['Covariance structure V - replications over ''%s''\n'...
  548. 'Correlated repeated measures: %s'], ...
  549. varargin{2}.sF{r},cmstr);
  550. end
  551. xlabel(str);
  552. else
  553. text(.5,.5, 'Covariance not (yet) estimated.', 'HorizontalAlignment','center');
  554. end
  555. if isfield(varargin{2},'h')
  556. hPEstAx = axes('Position',[.07 .315 .6 .025],...
  557. 'DefaultTextInterpreter','TeX');
  558. hParEstIm = imagesc(varargin{2}.h',clim);
  559. set(hPEstAx,...
  560. 'XLim',[0,length(varargin{2}.h)]+.5,'XTick',[1:length(varargin{2}.h)-1]+.5,...
  561. 'XTickLabel','',...
  562. 'YLim',[0,1]+.5,'YDir','reverse','YTick',[],...
  563. 'Box','on','TickDir','in','XGrid','on','GridLineStyle','-');
  564. xlabel('hyperparameter estimates')
  565. set(hParEstIm,'UserData',varargin{2}.h)
  566. set(hParEstIm,'ButtonDownFcn','spm_DesRep(''SurfHPEstIm_CB'')')
  567. else
  568. hPEstAx = [];
  569. end
  570. spm_figure('NewPage',[hCovMtx;get(hCovMtx,'Children');hPEstAx;get(hPEstAx,'Children');hCovMtxSc])
  571. %-Show components of covariance matrix
  572. %--------------------------------------------------------------------------
  573. if isfield(varargin{2},'Vi')
  574. for k = 1:length(varargin{2}.Vi)
  575. %-Display covariance component xVi.Vi{k}
  576. %------------------------------------------------------------------
  577. hCovMtx(k+1) = axes('Position',[.07 .4 .6 .4]);
  578. hCovMtxIm(k+1) = imagesc(varargin{2}.Vi{k});
  579. xlabel(sprintf('Covariance component Vi{%d}', k));
  580. if k<length(varargin{2}.Vi)
  581. spm_figure('NewPage',[hCovMtx(k+1);get(hCovMtx(k+1),'Children')])
  582. end
  583. end
  584. if spm_figure('#page')>1
  585. spm_figure('NewPage',[hCovMtx(k+1);get(hCovMtx(k+1),'Children')])
  586. end
  587. end
  588. %==========================================================================
  589. case {'desmtx','desorth'} %-Display design matrix / design orthogonality
  590. %==========================================================================
  591. % spm_DesRep('DesMtx',xX,fnames,xs)
  592. % spm_DesRep('DesOrth',xX)
  593. if nargin<2, error('insufficient arguments'), end
  594. if ~isstruct(varargin{2}), error('design matrix structure required'), end
  595. if nargin<3, fnames={}; else fnames=varargin{3}; end
  596. if nargin<4, xs=[]; else xs=varargin{4}; end
  597. desmtx = strcmpi(varargin{1},'desmtx');
  598. %-Locate DesMtx (X), scaled DesMtx (nX) & get parameter names (Xnames)
  599. %--------------------------------------------------------------------------
  600. if isfield(varargin{2},'xKXs') && ...
  601. ~isempty(varargin{2}.xKXs) && isstruct(varargin{2}.xKXs)
  602. iX = 1;
  603. [nScan,nPar] = size(varargin{2}.xKXs.X);
  604. elseif isfield(varargin{2},'X') && ~isempty(varargin{2}.X)
  605. iX = 0;
  606. [nScan,nPar] = size(varargin{2}.X);
  607. else
  608. error('Can''t find DesMtx in this structure!')
  609. end
  610. if isfield(varargin{2},'nKX') && ~isempty(varargin{2}.nKX)
  611. inX = 1; else inX = 0; end
  612. if isfield(varargin{2},'name') && ~isempty(varargin{2}.name)
  613. Xnames = varargin{2}.name; else Xnames = {}; end
  614. %-Compute design orthogonality matrix if DesOrth
  615. %--------------------------------------------------------------------------
  616. if ~desmtx
  617. if iX
  618. tmp = sqrt(sum(varargin{2}.xKXs.X.^2));
  619. O = varargin{2}.xKXs.X'*varargin{2}.xKXs.X./kron(tmp',tmp);
  620. tmp = sum(varargin{2}.xKXs.X);
  621. else
  622. tmp = sqrt(sum(varargin{2}.X.^2));
  623. O = varargin{2}.X'*varargin{2}.X./kron(tmp',tmp);
  624. tmp = sum(varargin{2}.X);
  625. end
  626. tmp = abs(tmp)<eps*1e5;
  627. bC = kron(tmp',tmp);
  628. end
  629. %-Display
  630. %==========================================================================
  631. %-Get graphics window & FontSizes
  632. %--------------------------------------------------------------------------
  633. Fgraph = spm_figure('GetWin','Graphics');
  634. spm_results_ui('Clear',Fgraph,0)
  635. FS = spm('FontSizes');
  636. %-Title
  637. %--------------------------------------------------------------------------
  638. hTax = axes('Position',[0.03,0,0.94,1],...
  639. 'DefaultTextFontSize',FS(9),...
  640. 'XLim',[0,1],'YLim',[0,1],...
  641. 'Visible','off');
  642. str='Statistical analysis: Design'; if ~desmtx, str=[str,' orthogonality']; end
  643. text(0.5,0.95,str,'Fontsize',FS(14),'Fontweight','Bold',...
  644. 'HorizontalAlignment','center');
  645. line('Parent',hTax,...
  646. 'XData',[0.3 0.7],'YData',[0.92 0.92],'LineWidth',3,'Color','r');
  647. %-Display design matrix
  648. %--------------------------------------------------------------------------
  649. hDesMtx = axes('Position',[.07 .4 .6 .4]);
  650. if inX %-Got a scaled DesMtx
  651. hDesMtxIm = image((varargin{2}.nKX + 1)*32);
  652. elseif iX %-No scaled DesMtx, DesMtx in .xKXs structure
  653. hDesMtxIm = image((spm_DesMtx('sca',varargin{2}.xKXs.X,Xnames) + 1)*32);
  654. else %-No scaled DesMtx, no .xKXs, DesMtx in .X
  655. hDesMtxIm = image((spm_DesMtx('sca',varargin{2}.X, Xnames) + 1)*32);
  656. end
  657. STick = spm_DesRep('ScanTick',nScan,32);
  658. PTick = spm_DesRep('ScanTick',nPar,32);
  659. set(hDesMtx,'TickDir','out',...
  660. 'XTick',PTick,'XTickLabel','',...
  661. 'YTick',STick,'YTickLabel','')
  662. if desmtx
  663. xlabel('parameters'), ylabel('images')
  664. else
  665. ylabel('design matrix')
  666. end
  667. %-Parameter names
  668. if ~isempty(Xnames)
  669. axes('Position',[.07 .8 .6 .1],'Visible','off',...
  670. 'DefaultTextFontSize',FS(8),'DefaultTextInterpreter','TeX',...
  671. 'XLim',[0,nPar]+0.5)
  672. for i=PTick, text(i,.05,Xnames{i},'Rotation',90), end
  673. end
  674. %-Filenames
  675. % ( Show at most 32, showing every 2nd/3rd/4th/... as necessary to pair )
  676. % ( down to <32 items. Always show last item so #images is indicated. )
  677. if desmtx && ~isempty(fnames)
  678. axes('Position',[.68 .4 .3 .4],'Visible','off',...
  679. 'DefaultTextFontSize',FS(8),...
  680. 'YLim',[0,nScan]+0.5,'YDir','Reverse')
  681. for i = STick
  682. try
  683. str = strrep(fnames(i,:),'\','/');
  684. catch
  685. str = strrep(fnames{i},'\','/');
  686. end
  687. text(0,i,spm_file(str,'short35'));
  688. end
  689. end
  690. %-Setup callbacks to allow interrogation of design matrix
  691. %--------------------------------------------------------------------------
  692. if iX, set(hDesMtxIm,'UserData',...
  693. struct('X',varargin{2}.xKXs.X,'Xnames',{Xnames},'fnames',{fnames}))
  694. else set(hDesMtxIm,'UserData',...
  695. struct('X',varargin{2}.X, 'Xnames',{Xnames},'fnames',{fnames}))
  696. end
  697. set(hDesMtxIm,'ButtonDownFcn','spm_DesRep(''SurfDesMtx_CB'')')
  698. if desmtx
  699. %-Parameter estimability/uniqueness
  700. %----------------------------------------------------------------------
  701. hPEstAx = axes('Position',[.07 .315 .6 .025],...
  702. 'DefaultTextInterpreter','TeX');
  703. if iX, est = spm_SpUtil('IsCon',varargin{2}.xKXs);
  704. else est = spm_SpUtil('IsCon',varargin{2}.X); end
  705. hParEstIm = image((est+1)*32);
  706. set(hPEstAx,...
  707. 'XLim',[0,nPar]+.5,'XTick',[1:nPar-1]+.5,'XTickLabel','',...
  708. 'YLim',[0,1]+.5,'YDir','reverse','YTick',[],...
  709. 'Box','on','TickDir','in','XGrid','on','GridLineStyle','-');
  710. xlabel('parameter estimability')
  711. text((nPar+0.5 + nPar/30),1,...
  712. '(gray \rightarrow \beta not uniquely specified)',...
  713. 'Interpreter','TeX','FontSize',FS(8))
  714. set(hParEstIm,'UserData',struct('est',est,'Xnames',{Xnames}))
  715. set(hParEstIm,'ButtonDownFcn','spm_DesRep(''SurfEstIm_CB'')')
  716. else
  717. %-Design orthogonality
  718. %----------------------------------------------------------------------
  719. hDesO = axes('Position',[.07 .18 .6 .2]);
  720. tmp = 1-abs(O); tmp(logical(tril(ones(nPar),-1))) = 1;
  721. hDesOIm = image(tmp*64);
  722. set(hDesO,'Box','off','TickDir','out',...
  723. 'XaxisLocation','top','XTick',PTick,'XTickLabel','',...
  724. 'YaxisLocation','right','YTick',PTick,'YTickLabel','',...
  725. 'YDir','reverse')
  726. tmp = [1,1]'*[[0:nPar]+0.5];
  727. line('Xdata',tmp(1:end-1)','Ydata',tmp(2:end)')
  728. xlabel('design orthogonality')
  729. set(get(hDesO,'Xlabel'),'Position',[0.5,nPar,0],...
  730. 'HorizontalAlignment','left',...
  731. 'VerticalAlignment','top')
  732. set(hDesOIm,...
  733. 'UserData',struct('O',O,'bC',bC,'Xnames',{Xnames}),...
  734. 'ButtonDownFcn','spm_DesRep(''SurfDesO_CB'')')
  735. if ~isempty(Xnames)
  736. axes('Position',[.69 .18 0.01 .2],'Visible','off',...
  737. 'DefaultTextFontSize',FS(10),...
  738. 'DefaultTextInterpreter','TeX',...
  739. 'YDir','reverse','YLim',[0,nPar]+0.5)
  740. for i=PTick
  741. text(0,i,Xnames{i},'HorizontalAlignment','left')
  742. end
  743. end
  744. end
  745. %-Design descriptions
  746. %--------------------------------------------------------------------------
  747. if desmtx
  748. str = 'Design description...';
  749. line('Parent',hTax,...
  750. 'XData',[0.3 0.7],'YData',[0.28 0.28],'LineWidth',3,'Color','r')
  751. hAx = axes('Position',[0.03,0.05,0.94,0.22],'Visible','off');
  752. else
  753. str = '';
  754. line('Parent',hTax,...
  755. 'XData',[0.3 0.7],'YData',[0.14 0.14],'LineWidth',3,'Color','r')
  756. hAx = axes('Position',[0.03,0.05,0.94,0.08],'Visible','off');
  757. xs = struct('Measure', ['abs. value of cosine of angle between ',...
  758. 'columns of design matrix'],...
  759. 'Scale', {{ 'black - colinear (cos=+1/-1)';...
  760. 'white - orthogonal (cos=0)';...
  761. 'gray - not orthogonal or colinear'}});
  762. end
  763. if ~isempty(xs)
  764. set(hAx,'Units','points');
  765. AxPos = get(hAx,'Position');
  766. set(hAx,'YLim',[0,AxPos(4)])
  767. dy = FS(9); y0 = floor(AxPos(4)) -dy; y = y0;
  768. text(0.3,y,str,...
  769. 'HorizontalAlignment','Center',...
  770. 'FontWeight','Bold','FontSize',FS(11))
  771. y=y-2*dy;
  772. for sf = fieldnames(xs)'
  773. text(0.3,y,[strrep(sf{1},'_',' '),' :'],...
  774. 'HorizontalAlignment','Right','FontWeight','Bold',...
  775. 'FontSize',FS(9))
  776. s = xs.(sf{1});
  777. if ~iscellstr(s), s={s}; end
  778. for i=1:numel(s)
  779. text(0.31,y,s{i},'FontSize',FS(9))
  780. y=y-dy;
  781. end
  782. end
  783. end
  784. %-Pop up the Graphics window
  785. %--------------------------------------------------------------------------
  786. figure(Fgraph)
  787. %==========================================================================
  788. case 'fmridesmtx' %-Interactive review of fMRI design matrix
  789. %==========================================================================
  790. %spm_DesRep('fMRIDesMtx',SPM,s,i)
  791. SPM = varargin{2};
  792. Sess = SPM.Sess;
  793. if nargin < 4, i = 1; else i = varargin{4}; end
  794. if nargin < 3, s = 1; else s = varargin{3}; end
  795. %-Get Graphics window
  796. %--------------------------------------------------------------------------
  797. Fgraph = spm_figure('GetWin','Graphics');
  798. spm_results_ui('Clear',Fgraph,0)
  799. %-Trial-specific regressors - time domain
  800. %--------------------------------------------------------------------------
  801. sX = SPM.xX.X(Sess(s).row,Sess(s).col);
  802. rX = sX(:,Sess(s).Fc(i).i);
  803. subplot(2,2,1)
  804. plot(Sess(s).row,rX)
  805. xlabel('scan')
  806. ylabel('regressor[s]')
  807. title({'Time domain',['Regressors for ' Sess(s).Fc(i).name]})
  808. grid on
  809. axis tight
  810. %-Trial-specific regressors - frequency domain
  811. %--------------------------------------------------------------------------
  812. subplot(2,2,2)
  813. gX = abs(fft(rX)).^2;
  814. gX = gX*diag(1./sum(gX));
  815. q = size(gX,1);
  816. Hz = [0:(q - 1)]/(q*SPM.xY.RT);
  817. q = 2:fix(q/2);
  818. plot(Hz(q),gX(q,:))
  819. HPF = SPM.xX.K(s).HParam;
  820. patch([0 1 1 0]/HPF,[0 0 1 1]*max(max(gX)),[1 1 1]*.9,'facealpha',.5);
  821. xlabel('Frequency (Hz)')
  822. ylabel('relative spectral density')
  823. h=title(['Frequency domain',sprintf('\n'), ' {\bf',num2str(HPF),'}', ...
  824. ' second High-pass filter'],'Interpreter','Tex');
  825. grid on
  826. axis tight
  827. % if trial (as opposed to trial x trial interaction)
  828. %--------------------------------------------------------------------------
  829. if length(Sess(s).U) >= i
  830. % Basis set and peristimulus sampling
  831. %----------------------------------------------------------------------
  832. subplot(2,2,3)
  833. dt = Sess(s).U(i).dt;
  834. RT = SPM.xY.RT;
  835. t = [1:size(SPM.xBF.bf,1)]*dt;
  836. pst = Sess(s).U(i).pst;
  837. plot(t,SPM.xBF.bf,pst,0*pst,'.','MarkerSize',16)
  838. str = sprintf('TR = %0.2fs',RT);
  839. xlabel({'time {secs}' str sprintf('%0.0fms time bins',1000*dt)})
  840. title({'Basis set and peristimulus sampling' SPM.xBF.name})
  841. axis tight
  842. grid on
  843. % if a paramteric variate is specified
  844. %----------------------------------------------------------------------
  845. for p = 1:length(Sess(s).U(i).P)
  846. if Sess(s).U(i).P(p).h
  847. % onsets and parametric modulation
  848. %------------------------------------------------------------------
  849. subplot(2,2,4)
  850. ons = Sess(s).U(i).ons;
  851. plot(ons,Sess(s).U(i).P(p).P,'.','MarkerSize',8)
  852. xlabel('time {secs}')
  853. title('Parameters')
  854. grid on
  855. hold on
  856. end
  857. end
  858. end
  859. %-Pop up Graphics figure window
  860. %--------------------------------------------------------------------------
  861. figure(Fgraph);
  862. %==========================================================================
  863. case 'covs' %-Plot and describe covariates (one per page)
  864. %==========================================================================
  865. % spm_DesRep('Covs',xX,xC)
  866. if nargin<3, error('insufficient arguments'), end
  867. xC = varargin{3}; %-Struct array of covariate information
  868. if ~isstruct(varargin{2}), error('design matrix structure required'), end
  869. if isempty(xC), spm('alert!','No covariates!',mfilename), return, end
  870. %-Get graphics window & window scaling
  871. Fgraph = spm_figure('GetWin','Graphics');
  872. spm_results_ui('Clear',Fgraph,0)
  873. FS = spm('FontSizes');
  874. %-Title
  875. %--------------------------------------------------------------------------
  876. hTax = axes('Position',[0.03,0,0.94,1],...
  877. 'DefaultTextFontSize',FS(9),...
  878. 'XLim',[0,1],'YLim',[0,1],...
  879. 'Visible','off');
  880. text(0.5,0.95,'Statistical analysis: Covariates',...
  881. 'Fontsize',FS(14),'Fontweight','Bold',...
  882. 'HorizontalAlignment','center')
  883. text(0.5,0.82,'(covariates plotted over transposed design matrix)',...
  884. 'FontSize',FS(8),'HorizontalAlignment','center')
  885. line('XData',[0.3 0.7],'YData',[0.92 0.92],'LineWidth',3,'Color','r')
  886. line('XData',[0.3 0.7],'YData',[0.44 0.44],'LineWidth',3,'Color','r')
  887. %-Design matrix (as underlay for plots) and parameter names
  888. %--------------------------------------------------------------------------
  889. [nScan,nPar] = size(varargin{2}.X);
  890. if isfield(varargin{2},'name') && ~isempty(varargin{2}.name)
  891. Xnames = varargin{2}.name; else Xnames = {}; end
  892. %-Design matrix
  893. hDesMtx = axes('Position',[.1 .5 .7 .3]);
  894. if isfield(varargin{2},'nKX') && ~isempty(varargin{2}.nKX)
  895. image(varargin{2}.nKX'*32+32)
  896. elseif isfield(varargin{2},'xKXs') && ~isempty(varargin{2}.xKXs)
  897. image(spm_DesMtx('sca',varargin{2}.xKXs.X,Xnames)*32+32)
  898. else
  899. image(spm_DesMtx('sca',varargin{2}.X,Xnames)*32+32)
  900. end
  901. set(hDesMtx,'Visible','off')
  902. %-Parameter names
  903. hParAx = axes('Position',[.8 .5 .2 .3],'Visible','off',...
  904. 'DefaultTextFontSize',FS(8),'DefaultTextInterpreter','TeX',...
  905. 'YLim',[0.5,nPar+0.5],'YDir','Reverse');
  906. for i = 1:nPar, hPNames(i) = text(.05,i,Xnames{i}); end
  907. %-Covariates - one page each
  908. %--------------------------------------------------------------------------
  909. for i = 1:length(xC)
  910. %-Title
  911. %----------------------------------------------------------------------
  912. hSTitle = text(0.5,0.87,sprintf('%d : %s',i,xC(i).rcname),...
  913. 'Parent',hTax,...
  914. 'HorizontalAlignment','center',...
  915. 'FontSize',FS(13),'FontWeight','Bold');
  916. %-Plot
  917. %----------------------------------------------------------------------
  918. hAx = axes('Position',[.1 .5 .7 .3],...
  919. 'TickDir','out','Box','off','Color','none',...
  920. 'NextPlot','add',...
  921. 'XLim',[0,nScan]+0.5);
  922. plot(xC(i).rc,'LineWidth',2)
  923. if nScan<48, plot(xC(i).rc,'.k','MarkerSize',20); end
  924. xlabel('image #')
  925. ylabel('covariate value')
  926. %-Descriptions
  927. %----------------------------------------------------------------------
  928. hDAx = axes('Position',[0.03,0.1,0.94,0.30],'Visible','off');
  929. set(hDAx,'Units','points');
  930. tmp = get(hDAx,'Position');
  931. set(hDAx,'YLim',[0,tmp(4)])
  932. dy = FS(9); y0 = floor(tmp(4)) -dy; y = y0;
  933. %-Description strings from xC(i).descrip
  934. text(0.3,y,'Details :',...
  935. 'HorizontalAlignment','Right',...
  936. 'FontWeight','Bold','FontSize',FS(9))
  937. s = xC(i).descrip;
  938. if ~iscellstr(s), s={s}; end
  939. for j=1:numel(s)
  940. text(0.31,y,s{j},'FontSize',FS(9))
  941. y=y-dy;
  942. end
  943. y=y-dy;
  944. %-Key (if block of covariates entered)
  945. %----------------------------------------------------------------------
  946. if size(xC(i).rc,2)>1
  947. ColorOrder = get(hAx,'ColorOrder');
  948. text(0.3,y,'Key :',...
  949. 'HorizontalAlignment','Right',...
  950. 'FontWeight','Bold','FontSize',FS(9))
  951. for j = 1:size(xC(i).rc,2)
  952. color = ColorOrder(mod(j-1,size(ColorOrder,1))+1,:);
  953. if size(xC(i).rc,2)==length(xC(i).cname)
  954. str = xC(i).cname{j};
  955. else
  956. str = sprintf('column %d',j);
  957. end
  958. text(0.31,y,str,'FontSize',FS(9),...
  959. 'Color',color)
  960. text(0.5,xC(i).rc(1,j),[str,' \rightarrow'],...
  961. 'Parent',hAx,...
  962. 'FontSize',FS(8),'FontWeight','Bold',...
  963. 'HorizontalAlignment','Right',...
  964. 'Interpreter','TeX',...
  965. 'Color',color)
  966. y=y-dy;
  967. end
  968. y=y-dy;
  969. end
  970. %-Associated parameters
  971. %----------------------------------------------------------------------
  972. text(0.3,y,'Design matrix columns :',...
  973. 'HorizontalAlignment','Right',...
  974. 'FontWeight','Bold','FontSize',FS(9))
  975. if isempty(xC(i).cols)
  976. text(0.31,y,'(none)','FontSize',FS(9))
  977. else
  978. for j = xC(i).cols
  979. text(0.31,y,sprintf('%d : %s',j,Xnames{j}),...
  980. 'FontSize',FS(9),'Interpreter','TeX')
  981. y=y-dy;
  982. end
  983. end
  984. y=y-dy;
  985. %-Highlight parameter names
  986. %----------------------------------------------------------------------
  987. hCurPNames = hPNames(xC(i).cols);
  988. set(hCurPNames,'Color','r','FontWeight','Bold','FontSize',FS(8))
  989. %-Paginate (if more than one covariate)
  990. %----------------------------------------------------------------------
  991. if length(xC)>1
  992. spm_figure('NewPage',[hSTitle; hAx; get(hAx,'Children');...
  993. hCurPNames; hDAx; get(hDAx,'Children')]);
  994. end
  995. end
  996. %-Pop up the Graphics window
  997. %--------------------------------------------------------------------------
  998. figure(Fgraph)
  999. %==========================================================================
  1000. case 'scantick'
  1001. %==========================================================================
  1002. % spm_DesRep('ScanTick',nScan,lim)
  1003. % ( Show at most 32, showing every 2nd/3rd/4th/... as necessary to pair )
  1004. % ( down to <32 items. Always show last item so #images is indicated. )
  1005. if nargin<3, lim=32; else lim=varargin{3}; end
  1006. if nargin<2, error('insufficient arguments'), end
  1007. nScan = varargin{2};
  1008. p = max(1,ceil(nScan/lim));
  1009. s = 1:p:nScan; s(end)=nScan;
  1010. varargout = {s,lim};
  1011. %==========================================================================
  1012. case {'surfdesmtx_cb','surfdesmtxmo_cb','surfdesmtxup_cb'} %-Surf DesMtx
  1013. %==========================================================================
  1014. % spm_DesRep('SurfDesMtx_CB')
  1015. % spm_DesRep('SurfDesMtxMo_CB')
  1016. % spm_DesRep('SurfDesMtxUp_CB')
  1017. h = get(gca,'Xlabel');
  1018. if strcmpi(varargin{1},'surfdesmtxup_cb')
  1019. UD = get(h,'UserData');
  1020. set(h,'String',UD.String,'Interpreter',UD.Interpreter,...
  1021. 'UserData',UD.UserData)
  1022. set(gcbf,'WindowButtonMotionFcn','','WindowButtonUpFcn','')
  1023. return
  1024. end
  1025. if strcmpi(varargin{1},'surfdesmtx_cb')
  1026. UD = struct('String', get(h,'String'),...
  1027. 'Interpreter', get(h,'Interpreter'),...
  1028. 'UserData', get(h,'UserData'));
  1029. set(h,'UserData',UD)
  1030. set(gcbf,'WindowButtonMotionFcn','spm_DesRep(''SurfDesMtxMo_CB'')',...
  1031. 'WindowButtonUpFcn','spm_DesRep(''SurfDesMtxUp_CB'')')
  1032. end
  1033. mm = [get(gca,'YLim')',get(gca,'XLim')']+[.5,.5;-.5,-.5];
  1034. ij = get(gca,'CurrentPoint');
  1035. ij = round(min(max(ij(1,[2,1]),mm(1,:)),mm(2,:)));
  1036. istr = 'none';
  1037. switch get(gcbf,'SelectionType')
  1038. case 'normal'
  1039. try, str = sprintf('X(%d,%d) = %g',ij(1),ij(2),...
  1040. subsref(get(gco,'UserData'),...
  1041. struct('type',{'.','()'},'subs',{'X',{ij(1),ij(2)}})));
  1042. catch, str='(no cached design matrix to surf)'; end
  1043. case 'extend'
  1044. try, str = sprintf('Image %d: %s',ij(1),...
  1045. char(spm_file(...
  1046. subsref(get(gco,'UserData'),...
  1047. struct('type',{'.','()'},...
  1048. 'subs',{'fnames',{ij(1),':'}})),'short40')));
  1049. catch, str='(no cached image filenames to surf)'; end
  1050. case 'alt'
  1051. try, str = sprintf('Parameter %d: %s',ij(2),...
  1052. subsref(get(gco,'UserData'),...
  1053. struct('type',{'.','{}'},'subs',{'Xnames',{ij(2)}})));
  1054. istr = 'tex';
  1055. catch, str='(no cached parameter names to surf)'; end
  1056. case 'open'
  1057. try, assignin('base','ans',subsref(get(gco,'UserData'),...
  1058. struct('type',{'.'},'subs',{'X'})))
  1059. evalin('base','ans')
  1060. catch, fprintf('%s GUI: can''t find design matrix\n',mfilename)
  1061. end
  1062. return
  1063. end
  1064. set(h,'String',str,'Interpreter',istr)
  1065. %==========================================================================
  1066. case {'surfestim_cb','surfestimmo_cb','surfestimup_cb'} %-Surf ParEstIm
  1067. %==========================================================================
  1068. % spm_DesRep('SurfEstIm_CB')
  1069. % spm_DesRep('SurfEstImMo_CB')
  1070. % spm_DesRep('SurfEstImUp_CB')
  1071. h = get(gca,'Xlabel');
  1072. if strcmpi(varargin{1},'surfestimup_cb')
  1073. UD = get(h,'UserData');
  1074. set(h,'String',UD.String,'Interpreter',UD.Interpreter,...
  1075. 'UserData',UD.UserData)
  1076. set(gcbf,'WindowButtonMotionFcn','','WindowButtonUpFcn','')
  1077. return
  1078. end
  1079. if strcmpi(varargin{1},'surfestim_cb')
  1080. UD = struct( 'String', get(h,'String'),...
  1081. 'Interpreter', get(h,'Interpreter'),...
  1082. 'UserData', get(h,'UserData'));
  1083. set(h,'UserData',UD)
  1084. set(gcbf,'WindowButtonMotionFcn','spm_DesRep(''SurfEstImMo_CB'')',...
  1085. 'WindowButtonUpFcn', 'spm_DesRep(''SurfEstImUp_CB'')')
  1086. end
  1087. mm = [get(gca,'XLim')]+[.5,-.5];
  1088. i = get(gca,'CurrentPoint');
  1089. i = round(min(max(i(1,1),mm(1)),mm(2)));
  1090. istr = 'none';
  1091. switch get(gcbf,'SelectionType')
  1092. case 'normal'
  1093. try, tmp = {' (not unique)',' (unique)'};
  1094. str = sprintf('Parameter %d : %s%s',...
  1095. i,...
  1096. subsref(get(gco,'UserData'),...
  1097. struct('type',{'.','{}'},'subs',{'Xnames',{i}})),...
  1098. tmp{subsref(get(gco,'UserData'),...
  1099. struct('type',{'.','()'},'subs',{'est',{i}}))+1});
  1100. istr = 'tex';
  1101. catch, str='(no cached data to surf)'; end
  1102. case {'extend','alt'}
  1103. return
  1104. case 'open'
  1105. try, UD = get(gco,'UserData');
  1106. assignin('base','ans',...
  1107. subsref(get(gco,'UserData'),...
  1108. struct('type',{'.'},'subs',{'est'})))
  1109. evalin('base','ans')
  1110. catch, fprintf('%s GUI: can''t find design orthogonality\n',mfilename)
  1111. end
  1112. return
  1113. end
  1114. set(h,'String',str,'Interpreter',istr);
  1115. %==========================================================================
  1116. case {'surfdeso_cb','surfdesomo_cb','surfdesoup_cb'} %-Surf DesOrthIm
  1117. %==========================================================================
  1118. % spm_DesRep('SurfDesO_CB')
  1119. % spm_DesRep('SurfDesOMo_CB')
  1120. % spm_DesRep('SurfDesOUp_CB')
  1121. h = get(gca,'Xlabel');
  1122. if strcmpi(varargin{1},'surfdesoup_cb')
  1123. UD = get(h,'UserData');
  1124. set(h,'String',UD.String,'Interpreter',UD.Interpreter,...
  1125. 'UserData',UD.UserData)
  1126. set(gcbf,'WindowButtonMotionFcn','','WindowButtonUpFcn','')
  1127. return
  1128. end
  1129. if strcmpi(varargin{1},'surfdeso_cb')
  1130. UD = struct( 'String', get(h,'String'),...
  1131. 'Interpreter', get(h,'Interpreter'),...
  1132. 'UserData', get(h,'UserData'));
  1133. set(h,'UserData',UD)
  1134. set(gcbf,'WindowButtonMotionFcn','spm_DesRep(''SurfDesOMo_CB'')',...
  1135. 'WindowButtonUpFcn', 'spm_DesRep(''SurfDesOUp_CB'')')
  1136. end
  1137. mm = [get(gca,'YLim')',get(gca,'XLim')']+[.5,.5;-.5,-.5];
  1138. ij = get(gca,'CurrentPoint');
  1139. ij = round(min(max(ij(1,[2,1]),mm(1,:)),mm(2,:)));
  1140. if ij(1)>ij(2), return, end
  1141. istr = 'none';
  1142. switch get(gcbf,'SelectionType')
  1143. case 'normal'
  1144. try
  1145. UD = get(gco,'UserData');
  1146. if abs(abs(UD.O(ij(1),ij(2)))-1) < eps*1e1
  1147. str = '{\bf colinear}';
  1148. elseif abs(UD.O(ij(1),ij(2))) < eps*1e1
  1149. str = '{\bf orthogonal}';
  1150. else
  1151. str = '{\bf not orthogonal}';
  1152. end
  1153. if ~diff(ij), str=[str,' {\it(same column)}']; end
  1154. if UD.bC(ij(1),ij(2)), tmp=' ={\it r}'; else tmp=''; end
  1155. str = { sprintf('{\\bf %s} (col %d)',...
  1156. UD.Xnames{ij(1)},ij(1)),...
  1157. sprintf('& {\\bf %s} (col %d)',...
  1158. UD.Xnames{ij(2)},ij(2)),...
  1159. sprintf('cos(\\theta)%s = %1.2f',...
  1160. tmp,UD.O(ij(1),ij(2))),...
  1161. ['\rightarrow ',str]};
  1162. istr = 'tex';
  1163. catch, str='(no cached data to surf)'; end
  1164. case {'extend','alt'}
  1165. return
  1166. case 'open'
  1167. try, UD = get(gco,'UserData');
  1168. assignin('base','ans',UD.O)
  1169. evalin('base','ans')
  1170. catch, fprintf('%s GUI: can''t find design orthogonality\n',mfilename)
  1171. end
  1172. return
  1173. end
  1174. set(h,'String',str,'Interpreter',istr)
  1175. %==========================================================================
  1176. case {'surfcon_cb','surfconmo_cb','surfconup_cb'} %-Surf Contrast
  1177. %==========================================================================
  1178. % spm_DesRep('SurfCon_CB')
  1179. % spm_DesRep('SurfConOMo_CB')
  1180. % spm_DesRep('SurfConOUp_CB')
  1181. cUD = get(gco,'UserData');
  1182. if ~isstruct(cUD) || ~isfield(cUD,'h')
  1183. warning('contrast GUI objects setup incorrectly'), return
  1184. end
  1185. h = cUD.h;
  1186. if strcmpi(varargin{1},'surfconup_cb')
  1187. UD = get(h,'UserData');
  1188. set(h,'String',UD.String,'Interpreter',UD.Interpreter,...
  1189. 'UserData',UD.UserData)
  1190. set(gcbf,'WindowButtonMotionFcn','','WindowButtonUpFcn','')
  1191. return
  1192. end
  1193. if strcmpi(varargin{1},'surfcon_cb')
  1194. UD = struct( 'String', get(h,'String'),...
  1195. 'Interpreter', get(h,'Interpreter'),...
  1196. 'UserData', get(h,'UserData'));
  1197. set(h,'UserData',UD)
  1198. set(gcbf,'WindowButtonMotionFcn','spm_DesRep(''SurfConMo_CB'')',...
  1199. 'WindowButtonUpFcn', 'spm_DesRep(''SurfConUp_CB'')')
  1200. end
  1201. mm = [get(gca,'YLim')',get(gca,'XLim')']+[.5,.5;-.5,-.5];
  1202. ij = get(gca,'CurrentPoint');
  1203. ij = round(min(max(ij(1,[2,1]),mm(1,:)),mm(2,:)));
  1204. istr = 'none';
  1205. switch get(gcbf,'SelectionType')
  1206. case 'normal'
  1207. try
  1208. if cUD.i>0, str = sprintf('%d',cUD.i); else str = ''; end
  1209. switch get(gco,'Type')
  1210. case 'image'
  1211. str = sprintf('%s\\{F\\}: {\\bf%s} (%d,%d) = %.2f',...
  1212. str,cUD.xCon.name,ij(2),ij(1),...
  1213. cUD.xCon.c(ij(2),ij(1)));
  1214. case 'patch'
  1215. str = sprintf('%s\\{T\\}: {\\bf%s} (%d) = %.2f',...
  1216. str,cUD.xCon.name,ij(2),...
  1217. cUD.xCon.c(ij(2)));
  1218. otherwise, error('unexpected object type')
  1219. end
  1220. istr = 'TeX';
  1221. catch, str='(no cached data to surf)'; end
  1222. case {'alt','extend'}
  1223. return
  1224. case 'open'
  1225. try, assignin('base','ans',cUD.xCon.c')
  1226. evalin('base','ans')
  1227. catch, fprintf('%s GUI: can''t find contrast\n',mfilename)
  1228. end
  1229. return
  1230. end
  1231. set(h,'String',str,'Interpreter',istr);
  1232. %==========================================================================
  1233. case {'surfxvi_cb','surfxvimo_cb','surfxviup_cb'} %-Surf Xvi
  1234. %==========================================================================
  1235. % spm_DesRep('SurfxVi_CB')
  1236. % spm_DesRep('SurfxViMo_CB')
  1237. % spm_DesRep('SurfxViUp_CB')
  1238. h = get(gca,'Xlabel');
  1239. if strcmpi(varargin{1},'surfxviup_cb')
  1240. UD = get(h,'UserData');
  1241. set(h,'String',UD.String,'Interpreter',UD.Interpreter,...
  1242. 'UserData',UD.UserData)
  1243. set(gcbf,'WindowButtonMotionFcn','','WindowButtonUpFcn','')
  1244. return
  1245. end
  1246. if strcmpi(varargin{1},'surfxvi_cb')
  1247. UD = struct( 'String', get(h,'String'),...
  1248. 'Interpreter', get(h,'Interpreter'),...
  1249. 'UserData', get(h,'UserData'));
  1250. set(h,'UserData',UD)
  1251. set(gcbf,'WindowButtonMotionFcn','spm_DesRep(''SurfxViMo_CB'')',...
  1252. 'WindowButtonUpFcn', 'spm_DesRep(''SurfxViUp_CB'')')
  1253. end
  1254. mm = [get(gca,'YLim')',get(gca,'XLim')']+[.5,.5;-.5,-.5];
  1255. ij = get(gca,'CurrentPoint');
  1256. ij = round(min(max(ij(1,[2,1]),mm(1,:)),mm(2,:)));
  1257. istr = 'none';
  1258. switch get(gcbf,'SelectionType')
  1259. case 'normal'
  1260. try
  1261. str = sprintf('V(%d,%d) = %g',ij(1),ij(2),...
  1262. full(subsref(get(gco,'UserData'),...
  1263. struct('type',{'.','()'},'subs',{'V',{ij(1),ij(2)}}))));
  1264. catch
  1265. str = '(no cached covariance matrix to surf)';
  1266. end
  1267. case 'extend'
  1268. try
  1269. ind = 1:length(subsref(get(gco,'Userdata'),...
  1270. struct('type','.','subs','h')));
  1271. isel = false(size(ind));
  1272. for k = 1:length(ind)
  1273. isel(k) = subsref(get(gco,'UserData'),...
  1274. struct('type',{'.','{}','()'},'subs',{'Vi',{k},{ij(1),ij(2)}})) ~= 0;
  1275. end
  1276. if any(isel)
  1277. str = [sprintf('V(%d,%d): ',ij(1),ij(2)) sprintf('Vi{%d}',ind(isel))];
  1278. else
  1279. str = sprintf('no Vi at (%d,%d)',ij(1),ij(2));
  1280. end
  1281. catch
  1282. return
  1283. end
  1284. case 'alt'
  1285. return
  1286. case 'open'
  1287. try
  1288. assignin('base','ans',subsref(get(gco,'UserData'),...
  1289. struct('type',{'.'},'subs',{'V'})));
  1290. evalin('base','ans');
  1291. catch
  1292. fprintf('%s GUI: can''t find covariance matrix\n',mfilename)
  1293. end
  1294. return
  1295. end
  1296. set(h,'String',str,'Interpreter',istr)
  1297. %==========================================================================
  1298. case {'surfhpestim_cb','surfhpestimmo_cb','surfhpestimup_cb'} %-Surf ParHpestim
  1299. %==========================================================================
  1300. % spm_DesRep('SurfHPEstim_CB')
  1301. % spm_DesRep('SurfHPEstimMo_CB')
  1302. % spm_DesRep('SurfHPEstimUp_CB')
  1303. h = get(gca,'Xlabel');
  1304. if strcmpi(varargin{1},'surfhpestimup_cb')
  1305. UD = get(h,'UserData');
  1306. set(h,'String',UD.String,'Interpreter',UD.Interpreter,...
  1307. 'UserData',UD.UserData)
  1308. set(gcbf,'WindowButtonMotionFcn','','WindowButtonUpFcn','')
  1309. return
  1310. end
  1311. if strcmpi(varargin{1},'surfhpestim_cb')
  1312. UD = struct( 'String', get(h,'String'),...
  1313. 'Interpreter', get(h,'Interpreter'),...
  1314. 'UserData', get(h,'UserData'));
  1315. set(h,'UserData',UD)
  1316. set(gcbf,'WindowButtonMotionFcn','spm_DesRep(''SurfHPEstimMo_CB'')',...
  1317. 'WindowButtonUpFcn', 'spm_DesRep(''SurfHPEstimUp_CB'')')
  1318. end
  1319. mm = [get(gca,'XLim')]+[.5,-.5];
  1320. i = get(gca,'CurrentPoint');
  1321. i = round(min(max(i(1,1),mm(1)),mm(2)));
  1322. istr = 'none';
  1323. switch get(gcbf,'SelectionType')
  1324. case 'normal'
  1325. try,
  1326. str = sprintf('Hyperparameter %d : %f',...
  1327. i,...
  1328. subsref(get(gco,'UserData'),...
  1329. struct('type',{'()'},'subs',{{i}})));
  1330. istr = 'tex';
  1331. catch, str='(no cached data to surf)'; end
  1332. case {'extend','alt'}
  1333. return
  1334. case 'open'
  1335. try, UD = get(gco,'UserData');
  1336. assignin('base','ans',...
  1337. get(gco,'UserData'));
  1338. evalin('base','ans')
  1339. catch, fprintf('%s GUI: can''t find hyperparameter estimates\n',mfilename)
  1340. end
  1341. return
  1342. end
  1343. set(h,'String',str,'Interpreter',istr);
  1344. %==========================================================================
  1345. otherwise %-Unknown action string
  1346. %==========================================================================
  1347. error(['Unknown action string: ',varargin{1}])
  1348. %==========================================================================
  1349. end
  1350. %==========================================================================
  1351. % function cb_menu(obj,evt,action,SPM,varargin)
  1352. %==========================================================================
  1353. function cb_menu(obj,evt,action,SPM,varargin)
  1354. switch action
  1355. case {'DesMtx','Files&Factors'}
  1356. try
  1357. filenames = reshape(cellstr(SPM.xY.P),size(SPM.xY.VY));
  1358. catch
  1359. filenames = {};
  1360. end
  1361. end
  1362. switch action
  1363. case 'DesMtx'
  1364. spm_DesRep('DesMtx',SPM.xX,...
  1365. filenames,...
  1366. SPM.xsDes);
  1367. case 'DesOrth'
  1368. spm_DesRep('DesOrth',SPM.xX);
  1369. case 'Files&Factors'
  1370. spm_DesRep('Files&Factors',...
  1371. filenames,...
  1372. SPM.xX.I,SPM.xC,SPM.xX.sF,SPM.xsDes);
  1373. case 'Covs'
  1374. spm_DesRep('Covs',SPM.xX,SPM.xC);
  1375. case 'fMRIDesMtx'
  1376. spm_DesRep('fMRIDesMtx',SPM,varargin{1},varargin{2});
  1377. case 'xVi'
  1378. spm_DesRep('xVi', SPM.xVi);
  1379. end