mardo - class constructor for MarsBaR design object inputs [defaults] params - one of: - string, specifying SPM design file, OR - structure, which can: contain SPM/MarsBaR design or contain fields for mardo object, which should include 'des_struct', containing design structure others - any other fields for mardo object (or children) passf - if 1, or not passed, will try children objects to see if they would like to own this design outputs o - mardo object others - any unrecognized fields from params, others Synopsis -------- D = mardo('/my/spm/analysis/directory/SPM.mat'); % or load('/my/spm/analysis/directory/SPM.mat'); D = mardo(SPM); % or load('/my/spm/analysis/directory/SPM.mat'); D = mardo(struct('des_struct', SPM, 'verbose', 0)); % or D = mardo(SPM, struct('verbose', 0)); mardo is an object to contain SPM designs. It allows us to deal with different design formats by overloading functions in child objects, here for harmonizing between SPM2 and SPM99 designs. It is transparent, in the sense that it can be referenced as a structure, so to the user, it can appear as if the design continues to be the familiar old SPM structure. This constructor first checks for strings; it treats strings as filenames containing SPM designs, and loads the file. By now it should have an SPM design structure (passed or loaded). It then labels itself as a mardo design, and passes itself to candidate mardo design classes (99 and 2 type designs) for these classes to further claim the object. If the (99 or 2) classes claim the object, they return an object of class (99 or 2), which inherits the mardo class just created in this call to the object. Note the "passf" input flag; this is a trick to allow the other mardo classes (99 and 2) to create a mardo object for them to inherit, without this constructor passing the mardo object back to the other classes, creating an infinite loop. So, the flag is by default set to 1, and the newly created mardo object is passed to the other mardo classes for them to claim ownership. The other mardo classes can call this constructor with passf set to 0 in order for the constructor merely to make a mardo object, without passing back to the other classes. Note also the way that the constructor passes out fields in the input structures that it does not recognize. This is so apparently useless field information can be passed to child objects for processing (or parent objects, but mardo does not have a parent). Fields des_struct - structure containing SPM design verbose - flag; if 1, display text messages during processing flip_option - flag; only used on creation of the object. If 1, and the design not the same format as the current version of SPM on the path, then this constructor will flip the images in the design left to right. So, if an SPM99 design object is being created, and SPM2 is the version on the path, and flip_option is set to 1, then the images will be automatically flipped in the design, as the object is being created. Methods is_valid - returns 1 if des_struct contains a valid design is_fmri - returns 1 if design is modality 'fmri' is_marsed - returns 1 if design has been processed with MarsBaR is_mars_estimated - returns 1 if design has Mars estimation data is_spm_estimated - returns 1 if design has SPM estimation data modality - returns one of 'fmri','pet','unknown' verbose - whether reporting is verbose or not (1 or 0) type - returns design version string 'SPM2' or 'SPM99' block_rows - returns cell array, one cell per subject or session, containing indices of design rows for that subject/session block_means - returns means for each block in the design n_time_points - number of rows (time points) in design n_effects - number of columns (effects) in design ui_report - display design report and query menu in UI ui_report_fmri - design report + inspection tools for FMRI savestruct - saves design structure to file, with fields as variables des_struct - sets or gets design structure has_filter - returns 1 if the design contains a filter, NaN if not known apply_filter - applies design filter to data ui_get_filter - gets filter and stocks in design fill - fills design with filter, images, or default values data - get/set data in estimated design get_data - get data set_data - set_data contrasts - get/set contrasts has_contrasts - returns 1 if the design contains contrasts set_contrasts - set contrasts to design get_contrasts - returns contrasts if present add_contrasts - adds contrasts from a design, xCon struct or passed values ui_get_contrasts - runs spm_conman to choose contrasts, returns indices has_images - returns 1 if the design contains images, NaN if not known images - gets / sets images in design get_images - gets image vol structs if present set_images - sets images image_names - gets image names as cell array cd_images - changes root directory to design images prefix_images - adds, removes prefix from images names (e.g. 's') estimate - estimates design, given data compute_contrasts - computes contrasts, returns statistics structure stat_table - return statistic table report and structures for contrasts mars_spm_graph - runs graph UI, displays in SPM windows event_signal - calculates % signal change for (maybe compound) event event_fitted - gets fitted time course for (maybe compound) event event_regressor - returns regressor for given event type and duration ui_get_event - runs UI to select a single event ui_event_types - runs UI to select, create, edit event types. event_cols - returns column in design from given event $Id$
0001 function [o, others] = mardo(params, others, passf) 0002 % mardo - class constructor for MarsBaR design object 0003 % inputs [defaults] 0004 % params - one of: 0005 % - string, specifying SPM design file, OR 0006 % - structure, which can: 0007 % contain SPM/MarsBaR design or 0008 % contain fields for mardo object, which should include 0009 % 'des_struct', containing design structure 0010 % others - any other fields for mardo object (or children) 0011 % passf - if 1, or not passed, will try children objects to see if 0012 % they would like to own this design 0013 % 0014 % outputs 0015 % o - mardo object 0016 % others - any unrecognized fields from params, others 0017 % 0018 % Synopsis 0019 % -------- 0020 % D = mardo('/my/spm/analysis/directory/SPM.mat'); 0021 % % or 0022 % load('/my/spm/analysis/directory/SPM.mat'); 0023 % D = mardo(SPM); 0024 % % or 0025 % load('/my/spm/analysis/directory/SPM.mat'); 0026 % D = mardo(struct('des_struct', SPM, 'verbose', 0)); 0027 % % or 0028 % D = mardo(SPM, struct('verbose', 0)); 0029 % 0030 % mardo is an object to contain SPM designs. It allows us to deal with 0031 % different design formats by overloading functions in child objects, here 0032 % for harmonizing between SPM2 and SPM99 designs. It is transparent, in 0033 % the sense that it can be referenced as a structure, so to the user, it 0034 % can appear as if the design continues to be the familiar old SPM structure. 0035 % 0036 % This constructor first checks for strings; it treats strings as filenames 0037 % containing SPM designs, and loads the file. By now it should have an SPM 0038 % design structure (passed or loaded). It then labels itself as a mardo 0039 % design, and passes itself to candidate mardo design classes (99 and 2 type 0040 % designs) for these classes to further claim the object. If the (99 or 2) 0041 % classes claim the object, they return an object of class (99 or 2), which 0042 % inherits the mardo class just created in this call to the object. 0043 % 0044 % Note the "passf" input flag; this is a trick to allow the other mardo 0045 % classes (99 and 2) to create a mardo object for them to inherit, without 0046 % this constructor passing the mardo object back to the other classes, 0047 % creating an infinite loop. So, the flag is by default set to 1, and the 0048 % newly created mardo object is passed to the other mardo classes for them 0049 % to claim ownership. The other mardo classes can call this constructor 0050 % with passf set to 0 in order for the constructor merely to make a mardo 0051 % object, without passing back to the other classes. 0052 % 0053 % Note also the way that the constructor passes out fields in the input 0054 % structures that it does not recognize. This is so apparently useless 0055 % field information can be passed to child objects for processing (or 0056 % parent objects, but mardo does not have a parent). 0057 % 0058 % Fields 0059 % des_struct - structure containing SPM design 0060 % verbose - flag; if 1, display text messages during processing 0061 % flip_option - flag; only used on creation of the object. If 1, and the 0062 % design not the same format as the current version of SPM 0063 % on the path, then this constructor will flip the images 0064 % in the design left to right. So, if an SPM99 design 0065 % object is being created, and SPM2 is the version on the 0066 % path, and flip_option is set to 1, then the images will 0067 % be automatically flipped in the design, as the object is 0068 % being created. 0069 % 0070 % Methods 0071 % is_valid - returns 1 if des_struct contains a valid design 0072 % is_fmri - returns 1 if design is modality 'fmri' 0073 % is_marsed - returns 1 if design has been processed with MarsBaR 0074 % is_mars_estimated - returns 1 if design has Mars estimation data 0075 % is_spm_estimated - returns 1 if design has SPM estimation data 0076 % modality - returns one of 'fmri','pet','unknown' 0077 % verbose - whether reporting is verbose or not (1 or 0) 0078 % type - returns design version string 'SPM2' or 'SPM99' 0079 % block_rows - returns cell array, one cell per subject or session, 0080 % containing indices of design rows for that 0081 % subject/session 0082 % block_means - returns means for each block in the design 0083 % n_time_points - number of rows (time points) in design 0084 % n_effects - number of columns (effects) in design 0085 % ui_report - display design report and query menu in UI 0086 % ui_report_fmri - design report + inspection tools for FMRI 0087 % 0088 % savestruct - saves design structure to file, with fields as variables 0089 % des_struct - sets or gets design structure 0090 % 0091 % has_filter - returns 1 if the design contains a filter, NaN if not known 0092 % apply_filter - applies design filter to data 0093 % ui_get_filter - gets filter and stocks in design 0094 % fill - fills design with filter, images, or default values 0095 % 0096 % data - get/set data in estimated design 0097 % get_data - get data 0098 % set_data - set_data 0099 % 0100 % contrasts - get/set contrasts 0101 % has_contrasts - returns 1 if the design contains contrasts 0102 % set_contrasts - set contrasts to design 0103 % get_contrasts - returns contrasts if present 0104 % add_contrasts - adds contrasts from a design, xCon struct or passed values 0105 % ui_get_contrasts - runs spm_conman to choose contrasts, returns indices 0106 % 0107 % has_images - returns 1 if the design contains images, NaN if not known 0108 % images - gets / sets images in design 0109 % get_images - gets image vol structs if present 0110 % set_images - sets images 0111 % image_names - gets image names as cell array 0112 % cd_images - changes root directory to design images 0113 % prefix_images - adds, removes prefix from images names (e.g. 's') 0114 % 0115 % estimate - estimates design, given data 0116 % compute_contrasts - computes contrasts, returns statistics structure 0117 % stat_table - return statistic table report and structures for 0118 % contrasts 0119 % mars_spm_graph - runs graph UI, displays in SPM windows 0120 % 0121 % event_signal - calculates % signal change for (maybe compound) event 0122 % event_fitted - gets fitted time course for (maybe compound) event 0123 % event_regressor - returns regressor for given event type and duration 0124 % ui_get_event - runs UI to select a single event 0125 % ui_event_types - runs UI to select, create, edit event types. 0126 % event_cols - returns column in design from given event 0127 % 0128 % $Id$ 0129 0130 myclass = 'mardo'; 0131 cvs_v = marsbar('ver'); % was CVS version; now marsbar version 0132 0133 % Default flip option 0134 flippo = mars_struct('getifthere', ... 0135 spm('getglobal', 'MARS'), ... 0136 'OPTIONS', ... 0137 'statistics', ... 0138 'flip_option'); 0139 if isempty(flippo), flippo = 0; end 0140 0141 % Default object structure; see also paramfields.m 0142 defstruct = struct('des_struct', [],... 0143 'flip_option', flippo,... 0144 'verbose', 1); 0145 0146 if nargin < 1 0147 defstruct.cvs_version = cvs_v; 0148 o = class(defstruct, myclass); 0149 others = []; 0150 return 0151 end 0152 if nargin < 2 0153 others = []; 0154 end 0155 if nargin < 3 0156 passf = 1; 0157 end 0158 0159 % Deal with passed objects of this (or child) class 0160 if isa(params, myclass) 0161 o = params; 0162 % Check for simple form of call 0163 if isempty(others), return, end 0164 0165 % Otherwise, we are being asked to set fields of object 0166 [p others] = mars_struct('split', others, defstruct); 0167 if isfield(p, 'des_struct') 0168 error('Please set des_struct using des_struct method'); 0169 end 0170 if isfield(p, 'verbose'), o.verbose = p.verbose; end 0171 if isfield(p, 'flip_option'), o.flip_option = p.flip_option; end 0172 return 0173 end 0174 0175 % check inputs 0176 if ischar(params) % maybe filename 0177 fname = deblank(params); 0178 fname = spm_get('CPath', fname); 0179 params = load(fname); 0180 params.swd = fileparts(fname); 0181 else 0182 fname = ''; 0183 end 0184 if isstruct(params) 0185 if ~isfield(params, 'des_struct') 0186 % Appears to be an SPM design 0187 params = struct('des_struct', params); 0188 end 0189 end 0190 0191 % fill with other params, defaults, parse into fields for this object, 0192 % children 0193 params = mars_struct('ffillmerge', params, others); 0194 [params, others] = mars_struct('ffillsplit', defstruct, params); 0195 0196 % cvs version 0197 params.cvs_version = cvs_v; 0198 0199 % set the mardo object 0200 o = class(params, myclass); 0201 0202 % Return if des_struct is empty, there's nothing to do 0203 if isempty(o.des_struct), return, end 0204 0205 % If requested, pass to child objects to request ownership 0206 if passf 0207 % Check what object type is returned from each of the potential 0208 % constructors. If returns default (this) object type, the constructor 0209 % has disowned the design, and keep looking 0210 [o others] = mardo_99(o, others); 0211 if strcmp(class(o), myclass) 0212 [o others] = mardo_2(o, others); 0213 end 0214 if strcmp(class(o), myclass) 0215 [o others] = mardo_5(o, others); 0216 end 0217 end 0218 0219 % convert MarsBaR data field to object, if present 0220 if isfield(o.des_struct, 'marsY') 0221 o.des_struct.marsY = marsy(o.des_struct.marsY); 0222 end 0223 0224 % If the design was loaded from a file, and is 99 type then it may need 0225 % contrasts. If it was estimated in MarsBaR, try loading mars_xCon.mat in the 0226 % same directory. If it was estimated in SPM, try loading xCon.mat in the same 0227 % directory. 0228 if ~isempty(fname) & strcmp(type(o), 'SPM99') & ~has_contrasts(o) 0229 % We try to load contrasts from an xCon file 0230 [pn fn ext] = fileparts(fname); 0231 if is_mars_estimated(o) 0232 xcon_name = fullfile(pn, 'mars_xCon.mat') 0233 elseif is_spm_estimated(o) 0234 xcon_name = fullfile(pn, 'xCon.mat'); 0235 else 0236 xcon_name = ''; 0237 end 0238 if ~isempty(xcon_name) 0239 % There is a file to load 0240 if exist(xcon_name, 'file') 0241 xc = load(xcon_name); 0242 if isfield(xc, 'xCon') 0243 o = set_contrasts(o, xc.xCon); 0244 if verbose(o) 0245 disp(['Set contrasts from ' xcon_name]); 0246 end 0247 end 0248 elseif verbose(o) 0249 disp('Failed to load contrasts'); 0250 end 0251 end 0252 end 0253 0254 % Refresh contrasts if option specifies 0255 if is_mars_estimated(o) & mars_get_option('statistics', 'refresh_contrasts') 0256 o = refresh_contrasts(o); 0257 end 0258 0259 % sort out design image flipping 0260 dt = type(o); 0261 sv = mars_utils('spm_version'); 0262 maybe_flip = ~strcmp(dt, sv) & ismember('SPM99', {dt, sv}); 0263 if ~is_marsed(o) 0264 if sf_tf(has_images(o)) & maybe_flip 0265 flippo = flip_option(o); 0266 switch flippo 0267 case 1 0268 o = flip_images(o); 0269 add_str = ''; 0270 case 0 0271 add_str = 'not '; 0272 otherwise 0273 error(['Do not recognize flip option ' flippo]); 0274 end 0275 if verbose(o) 0276 fprintf([... 0277 'This a design from %s, but you are currently using %s\n',... 0278 'Data may be extracted from different sides in X (L/R)\n',... 0279 'when using this design with %s compared to %s.\n',... 0280 'NB mardo object has %sflipped the images for this design\n'],... 0281 dt, sv, dt, sv, add_str); 0282 end 0283 end % has_images, design/running SPM version differ 0284 % Add Mars tag 0285 o = mars_tag(o, struct(... 0286 'flipped', flip_option(o))); 0287 end 0288 0289 % resolve confusing field name in marsbar <= 0.23 0290 % ResMS was in fact the _Root_ Mean Square 0291 % The statistics routines treated the field correctly 0292 D = o.des_struct; 0293 if isfield(D, 'ResMS') 0294 if verbose(o) 0295 msg = {'Compatibility trivia: processed ResMS to ResidualMS'}; 0296 fprintf('\n%s',sprintf('%s\n',msg{:})); 0297 end 0298 D.ResidualMS = D.ResMS .^ 2; 0299 D = rmfield(D, 'ResMS'); 0300 o.des_struct = D; 0301 end 0302 0303 return 0304 0305 function r = sf_tf(d) 0306 if isnan(d), r = 0; 0307 else 0308 r = (d~=0); 0309 end 0310 return