|
| 1 | +function [D,Ic,changef] = add_contrasts(D, C, varargin) |
| 2 | +% method to add contrast definitions to design |
| 3 | +% |
| 4 | +% The function has many different formats |
| 5 | +% |
| 6 | +% FORMAT [D Ic changef] = add_contrasts(D, D2 [,Ic]) |
| 7 | +% |
| 8 | +% where D2 is a design. If there is no third argument, all the contrasts in |
| 9 | +% D2 will be added. If third argument (Ic) is passed, specifies which |
| 10 | +% contrasts in D2 to add. If Ic passed, and empty, or contains the string |
| 11 | +% 'ui', contrasts to add are fetched using the GUI |
| 12 | +% |
| 13 | +% OR |
| 14 | +% FORMAT [D Ic changef] = add_contrasts(D, xCon) |
| 15 | +% |
| 16 | +% where xCon is a structure in SPM contrast format containing contrasts to |
| 17 | +% add. If there is no third argument, all the contrasts in xCon will be |
| 18 | +% added. If third argument (Ic) is passed, specifies which contrasts in xCon |
| 19 | +% to add. If Ic passed, and empty, or contains the string 'ui', contrasts to |
| 20 | +% add are fetched using the GUI |
| 21 | +% |
| 22 | +% OR |
| 23 | +% FORMAT [D Ic changef] = add_contrasts(D, stat_struct) |
| 24 | +% where stat_struct has fields |
| 25 | +% 'names', string, or cell array of strings |
| 26 | +% 'types', string ('T' or 'F'), or cell array |
| 27 | +% 'set_actions', string ('c', 'X0' or 'iX0') or array |
| 28 | +% (see spm_FcUtil) |
| 29 | +% (field is optional, defaults to 'c') |
| 30 | +% 'values', matrix of values |
| 31 | +% |
| 32 | +% OR |
| 33 | +% FORMAT [D Ic changef] = add_contrasts(D, names, types, values) |
| 34 | +% where names, types, values are cell arrays of values, or values |
| 35 | +% (defined as above) |
| 36 | +% |
| 37 | +% OR |
| 38 | +% FORMAT [D Ic changef] = add_contrasts(D, names, types, set_actions, values) |
| 39 | +% where names, types, set_actions, values are cell arrays of values, or |
| 40 | +% values (defined as above) |
| 41 | +% |
| 42 | +% Returns |
| 43 | +% D - possibly modified SPM design |
| 44 | +% Ic - indices of specified contrasts as stored in D |
| 45 | +% changef - 1 if D has changed during call else 0 |
| 46 | +% |
| 47 | +% Contrast will not be added if it is already present, but the correct |
| 48 | +% index will be returned in Ic |
| 49 | +% |
| 50 | +% $Id$ |
| 51 | + |
| 52 | +if nargin < 2 |
| 53 | + error('Need contrasts to add'); |
| 54 | +end |
| 55 | + |
| 56 | +% Get parameters from current design |
| 57 | +SPM = des_struct(D); |
| 58 | +sX = SPM.xX.xKXs; |
| 59 | +xCon = SPM.xCon; |
| 60 | +v_f = verbose(D); |
| 61 | + |
| 62 | +% process inputs |
| 63 | +% The ``C`` variable will hold the xCon structure for the contrasts to add |
| 64 | +if isa(C, 'mardo') % design |
| 65 | + C = des_struct(C); |
| 66 | +end |
| 67 | +if isfield(C, 'xCon') % design structure |
| 68 | + C = C.xCon; |
| 69 | +end |
| 70 | +if isfield(C, 'STAT') % xCon structure |
| 71 | + % parse Ic input |
| 72 | + if nargin > 2 % There is Ic input |
| 73 | + Ic_in = varargin{1}; |
| 74 | + if isempty(Ic_in) | strcmp(Ic_in,'ui') |
| 75 | + D2 = set_contrasts(D, C, 0); |
| 76 | + Ic_in = ui_get_contrasts(D2,'T&F',Inf,... |
| 77 | + 'Select contrasts to merge','',1); |
| 78 | + end |
| 79 | + C = C(Ic_in); |
| 80 | + end |
| 81 | +else % contrast setting structure or values or cells |
| 82 | + if ~isstruct(C) % make stat_struct structure if not already passed |
| 83 | + C = sf_cell_to_conset(C, varargin{:}); |
| 84 | + end |
| 85 | + % make xCon structure from stat_struct |
| 86 | + C = sf_conset_to_xcon(C, sX); |
| 87 | +end |
| 88 | +% Initial xCon before adding new contrasts |
| 89 | +xc_len = length(xCon); |
| 90 | +old_xc_len = xc_len; |
| 91 | +% C contains the contrasts to add |
| 92 | +for i=1:length(C) |
| 93 | + % Update this contrast using our own filtered design |
| 94 | + c_i = refresh_con(C(i), sX); |
| 95 | + if xc_len == 0 % the xCon to add to is empty |
| 96 | + xCon = c_i; |
| 97 | + xc_len = 1; |
| 98 | + Ic(1) = 1; |
| 99 | + continue |
| 100 | + end |
| 101 | + % Check if we have this contrast already |
| 102 | + Ic(i) = spm_FcUtil('In', c_i, sX, xCon); |
| 103 | + if Ic(i) == 0 |
| 104 | + xc_len = xc_len+1; |
| 105 | + xCon(xc_len) = c_i; |
| 106 | + Ic(i) = xc_len; |
| 107 | + elseif v_f |
| 108 | + fprintf('\nContrast %s (type %s) already in xCon\n', ... |
| 109 | + c_i.name, c_i.STAT); |
| 110 | + end |
| 111 | +end |
| 112 | +changef = xc_len ~= old_xc_len; |
| 113 | +if changef |
| 114 | + SPM.xCon = xCon; |
| 115 | + D = des_struct(D, SPM); |
| 116 | +end |
| 117 | +return |
| 118 | + |
| 119 | +function xcon_re_entry = refresh_con(xcon_entry, sX) |
| 120 | +% Rebuild contrast structure from our own filtered design |
| 121 | +if isempty(xcon_entry.c) |
| 122 | + error('Empty c matrix for contrast, crashing because confused') |
| 123 | +end |
| 124 | +xcon_re_entry = spm_FcUtil('Set',... |
| 125 | + xcon_entry.name,... |
| 126 | + xcon_entry.STAT,... |
| 127 | + 'c',... |
| 128 | + xcon_entry.c,... |
| 129 | + sX); |
| 130 | + |
| 131 | +function C = sf_cell_to_conset(names, types, varargin) |
| 132 | +% makes contrast setting structure from cell input |
| 133 | +if nargin < 3 |
| 134 | + error('Need at least names, statistic types and values'); |
| 135 | +end |
| 136 | +C = struct(... |
| 137 | + 'names', names,... |
| 138 | + 'types', types); |
| 139 | +if nargin < 4 % values call |
| 140 | + values = varargin{1}; |
| 141 | + set_actions = 'c'; |
| 142 | +else % contrast types, values call |
| 143 | + set_actions = deal(varargin{1}); |
| 144 | + values = deal(varargin{2}); |
| 145 | +end |
| 146 | +C = struct(... |
| 147 | + 'names', names,... |
| 148 | + 'types', types,... |
| 149 | + 'set_actions', set_actions,... |
| 150 | + 'values', values); |
| 151 | +return |
| 152 | + |
| 153 | +function C = sf_conset_to_xcon(con_set, sX) |
| 154 | +% make xCon structure from cell or struct setting parameters |
| 155 | +if ~isfield(con_set, 'set_actions') |
| 156 | + [con_set.set_actions] = deal('c'); |
| 157 | +end |
| 158 | +n_e = size(sX.X, 2); |
| 159 | +for c = 1:length(con_set) |
| 160 | + c1 = con_set(c); |
| 161 | + if size(c1.values, 1) ~= n_e & ... |
| 162 | + size(c1.values, 2) == n_e |
| 163 | + c1.values = c1.values'; |
| 164 | + end |
| 165 | + C(c) = spm_FcUtil('Set',... |
| 166 | + c1.names,... |
| 167 | + c1.types,... |
| 168 | + c1.set_actions,... |
| 169 | + c1.values,... |
| 170 | + sX); |
| 171 | +end |
| 172 | +return |
0 commit comments