Returns indices of structs within a cell array that match certain criteria. an_st_idx = ensemble_find_analysis_struct(an_st_array, search_crit); Retrieves the indices of analysis structures within a cell array of analysis structures that match certain criteria, such as analyis type or values in fields of structures contained in the meta field associated with the analysis. This function is very useful for post-processing analyses that have been returned by some of the generic lower-level analysis functions such as ensemble_enum_hist. search_crit is a structure in which the field names should refer to fields in the data structure (an_st_array), e.g. type, vars, data. The value(s) of the criterion field in the search crit struct are the values of the criterion variable to match. Example, if you are looking for an analysis structure that has subject_id as one of the variables, the criterion field would be 'vars' and its value would be 'subject_id'
0001 function an_st_idxs = ensemble_find_analysis_struct(an_st_array, search_crit) 0002 % Returns indices of structs within a cell array that match certain criteria. 0003 % 0004 % an_st_idx = ensemble_find_analysis_struct(an_st_array, search_crit); 0005 % 0006 % Retrieves the indices of analysis structures within a cell array of analysis 0007 % structures that match certain criteria, such as analyis type or values in 0008 % fields of structures contained in the meta field associated with the 0009 % analysis. 0010 % 0011 % This function is very useful for post-processing analyses that have been returned 0012 % by some of the generic lower-level analysis functions such as 0013 % ensemble_enum_hist. 0014 % 0015 % search_crit is a structure in which the field names should refer to fields in 0016 % the data structure (an_st_array), e.g. type, vars, data. The value(s) of the 0017 % criterion field in the search crit struct are the values of the criterion 0018 % variable to match. 0019 % 0020 % Example, if you are looking for an analysis structure that has subject_id as 0021 % one of the variables, the criterion field would be 'vars' and its value would 0022 % be 'subject_id' 0023 0024 % 01/31/07 Petr Janata 0025 % 05/23/10 PJ - Fixed handling of an array of input structures 0026 0027 an_st_idxs = []; % Initialize the output variable to empty 0028 0029 if isstruct(an_st_array) 0030 an_st_array = {an_st_array}; 0031 end 0032 0033 na = length(an_st_array); % number of analyses in the list 0034 0035 % Set up a global mask for keeping track of which analysis structures survive 0036 % all of the criteria 0037 global_mask = true(1,na); 0038 0039 % Get a list of criterion fields that we are going to search on 0040 crit_fld_list = fieldnames(search_crit); 0041 ncrit_fld = length(crit_fld_list); 0042 0043 % Loop over top-level criterion fields 0044 for ifld = 1:ncrit_fld 0045 crit_fld = crit_fld_list{ifld}; 0046 0047 % Get a list of the analysis structures that contain this criterion field 0048 crit_fld_mask = cellfun(@isfield,an_st_array, repmat({crit_fld},1,na)); 0049 0050 % Make sure that at least some analysis structure had this mask 0051 if ~any(crit_fld_mask) 0052 fprintf('None of the analysis structures had the criterion field: %s\n', crit_fld); 0053 an_st_idxs = []; 0054 return 0055 end 0056 0057 % Check to see if the criterion field is itself a structure or if it contains 0058 % a criterion value 0059 crit_val = search_crit.(crit_fld); 0060 crit_val_is_struct = isstruct(crit_val); 0061 0062 % Either way, we want to extract the corresponding values from the analysis structure 0063 if isstr(crit_val) || crit_val_is_struct 0064 analysis_vals = cell(1,na); 0065 else 0066 analysis_vals = zeros(1,na)*NaN; % 05/01/07 - this might be a bug to size 0067 % it to na ? 0068 end 0069 if isstr(crit_val) || crit_val_is_struct 0070 analysis_vals(crit_fld_mask) = ... 0071 cellfun(@getfield,an_st_array(crit_fld_mask), ... 0072 repmat({crit_fld},1,sum(crit_fld_mask)), 'UniformOutput',false); 0073 else 0074 analysis_vals(crit_fld_mask) = ... 0075 cellfun(@getfield,an_st_array(crit_fld_mask), ... 0076 repmat({crit_fld},1,sum(crit_fld_mask))); 0077 end 0078 0079 if isstr(crit_val) 0080 analysis_vals(~crit_fld_mask) = repmat({''},1,sum(~crit_fld_mask)); 0081 end 0082 0083 % If the criterion value is not a structure, then match the analysis values 0084 % against the criterion values to get our mask. 0085 % 05/23/10 PJ - fixed handling of analysis_vals when it is an array of 0086 % cells. However, this may have broken situation when analysis_vals is 0087 % not a cell. Line 66 above: analysis_vals = zeros(1,na)*NaN; is suspect. 0088 curr_mask = false(1,na); 0089 if ~crit_val_is_struct 0090 for ia = 1:na 0091 if isstr(crit_val) && iscell(analysis_vals{ia}) 0092 curr_mask(ia) = any(ismember(analysis_vals{ia}, crit_val)); 0093 elseif isstr(crit_val) && isstr(analysis_vals{ia}) 0094 curr_mask(ia) = strcmp(crit_val,analysis_vals{ia}); 0095 else 0096 curr_mask(ia) = analysis_vals(ia) == crit_val; 0097 end 0098 end 0099 else 0100 % Otherwise, recursively call this function 0101 good_idxs = ensemble_find_analysis_struct(analysis_vals,crit_val); 0102 curr_mask(good_idxs) = true; 0103 end 0104 0105 global_mask = global_mask & curr_mask; 0106 0107 % Terminate the search if there are no more analyses to check out 0108 if ~any(global_mask) 0109 an_st_idxs = []; 0110 return 0111 end 0112 end % for ifld = 1:ncrit_fld 0113 0114 an_st_idxs = find(global_mask); 0115 0116 return