generate_fc.m 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. function [FCpre,pred_data,Fcorr] = generate_fc(SC,beta,ED,pred_var,model,FC)
  2. % GENERATE_FC Generation of synthetic functional connectivity matrices
  3. %
  4. % [FCpre,pred_data,Fcorr] = generate_fc(SC,beta,ED,{'SPLwei_log','SIwei_log'},FC)
  5. % [FCpre,pred_data] = generate_fc(SC,beta,[],{'SPLwei_log','SIwei_log'})
  6. %
  7. % Uses a vector beta of regression coefficients from the model
  8. % FC = pred_var*beta to predict FC. pred_var are structural-based network
  9. % measures derived from the structural connectivity network.
  10. %
  11. % Inputs:
  12. %
  13. % SC,
  14. % Weighted/unweighted undirected NxN Structural Connectivity matrix.
  15. %
  16. % beta,
  17. % Regression coefficients (vector). These may be obtained as an
  18. % output parameter from function predict_fc.m
  19. %
  20. % ED,
  21. % Euclidean distance matrix or upper triangular vector of the
  22. % matrix (optional)
  23. %
  24. % pred_var,
  25. % Set of M predictors. These can be given as an KxM array where
  26. % K = ((N*(N-1))/2) and M is the number of predictors.
  27. % Alternatively, pred_var can be a cell with the names of network
  28. % measures to be used as predictors. Accepted network measure
  29. % names are:
  30. % SPLbin - Shortest-path length (binary)
  31. % SPLwei_inv - Shortest-path length computed with an inv transform
  32. % SPLwei_log - Shortest-path length computed with a log transform
  33. % SPLdist - Shortest-path length computed with no transform
  34. % SIbin - Search Information of binary shortest-paths
  35. % SIwei_inv - Search Information of shortest-paths computed with an inv transform
  36. % SIwei_log - Search Information of shortest-paths computed with a log transform
  37. % SIdist - Search Information of shortest-paths computed with no transform
  38. % T - Path Transitivity
  39. % deltaMFPT - Column-wise z-scored mean first passage time
  40. % neighOverlap - Neighborhood Overlap
  41. % MI - Matching Index
  42. %
  43. % Predictors must be specified in the order that matches the
  44. % given beta values.
  45. %
  46. % model,
  47. % Specifies the order of the regression model used within
  48. % matlab's function regstats.m. 'model' can be any option
  49. % accepted by matlab's regstats.m function (e.g.'linear',
  50. % 'interaction' 'quadratic', etc). If no model is specified,
  51. % 'linear' is the default.
  52. %
  53. % FC,
  54. % Functional connections. FC can be a NxN symmetric matrix or a
  55. % ((N*(N-1))/2) x 1 vector containing the upper triangular
  56. % elements of the square FC matrix (excluding diagonal elements).
  57. % This argument is optional and only used to compute the
  58. % correlation between the predicted FC and empirical FC.
  59. %
  60. %
  61. % Outputs:
  62. %
  63. % FCpre,
  64. % Predicted NxN Functional Connectivity matrix
  65. %
  66. % pred_data,
  67. % KxM array of predictors.
  68. %
  69. % FCcorr,
  70. % Pearson Correlation between FCpred and FC
  71. %
  72. %
  73. % Reference: Goñi et al. (2014) PNAS 111: 833–838
  74. %
  75. %
  76. % Andrea Avena-Koenigsberger, Joaquin Goñi and Olaf Sporns; IU Bloomington, 2016
  77. [b1,b2] = size(beta);
  78. if b1 == 1 && b2 >= b1
  79. beta = beta'; % beta must be a column vector
  80. elseif b1 > 1 && b2 > 1
  81. error('beta must be a vector of scalar regression coefficients')
  82. end
  83. pred_names = {'SPLbin','SPLwei_inv','SPLwei_log','SPLdist','SIbin',...
  84. 'SIwei_inv','SIwei_log','SIdist','T','deltaMFPT','neighOverlap','MI'};
  85. % select model
  86. if ~exist('model','var') || isempty(model)
  87. model = 'linear';
  88. end
  89. N = size(SC,1);
  90. indx = find(triu(ones(N),1));
  91. if ~exist('pred_var','var') && ~isempty(ED)
  92. pred_var = {'ED','SPLwei_log','SI','T'};
  93. flag_var_names = true;
  94. flag_ED = true;
  95. elseif ~exist('pred_var','var') && isempty(ED)
  96. pred_var = {'SPLwei_log','SI','T'};
  97. flag_var_names = true;
  98. elseif exist('pred_var','var') && ~isnumeric(pred_var) && ~isempty(ED)
  99. flag_var_names = true;
  100. flag_ED = true;
  101. elseif exist('pred_var','var') && ~isnumeric(pred_var) && isempty(ED)
  102. flag_var_names = true;
  103. flag_ED = false;
  104. elseif exist('pred_var','var') && isnumeric(pred_var) && ~isempty(ED)
  105. flag_var_names = false;
  106. flag_ED = true;
  107. elseif exist('pred_var','var') && isnumeric(pred_var) && isempty(ED)
  108. flag_var_names = false;
  109. flag_ED = false;
  110. else
  111. err_str = '"pred_var" must be an KxM array of M predictors, or any of the following graph-measure names:';
  112. s1 = sprintf('SPLbin - Shortest-path length (binary) \n');
  113. s2 = sprintf('SPLwei_inv - Shortest-path length computed with an inv transform \n');
  114. s3 = sprintf('SPLwei_log - Shortest-path length computed with a log transform \n');
  115. s4 = sprintf('SPLdist - Shortest-path length computed with no transform \n');
  116. s5 = sprintf('SIbin - Search Information of binary shortest-paths \n');
  117. s6 = sprintf('SIwei_inv - Search Information of shortest-paths computed with an inv transform \n');
  118. s7 = sprintf('SIwei_log - Search Information of shortest-paths computed with a log transform \n');
  119. s8 = sprintf('SIdist - Search Information of shortest-paths computed with no transform \n');
  120. s9 = sprintf('T - Path Transitivity \n');
  121. s10 = sprintf('deltaMFPT - Column-wise z-scored mean first passage time \n');
  122. s11 = sprintf('neighOverlap - Neighborhood Overlap \n');
  123. s12 = sprintf('MI - Matching Index \n');
  124. error('%s \n %s %s %s %s %s %s %s %s %s %s %s %s',err_str,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12);
  125. end
  126. if flag_ED
  127. [n1,n2] = size(ED);
  128. if n1 == n2 && n1 == N
  129. % square ED matrix
  130. pred_data = ED(indx);
  131. elseif n1 == length(indx) && n2 == 1
  132. % ED is already an upper-triangle vector
  133. pred_data = ED;
  134. else
  135. error('ED must be square matrix or a vector containing the upper triangle of the square ED matrix \n')
  136. end
  137. else
  138. pred_data = [];
  139. end
  140. if flag_var_names
  141. fprintf('\n----------------------');
  142. fprintf('\n Selected predictors: \n');
  143. ind2start = size(pred_data,2);
  144. pred_data = [pred_data,zeros(length(indx),length(pred_var))];
  145. for v = 1:length(pred_var)
  146. var_ind = find(strcmp(pred_var{v},pred_names));
  147. switch var_ind
  148. case 1 %SPLbin
  149. fprintf('Shortest-path length (binary) \n\n');
  150. data = distance_wei_floyd(double(SC>0));
  151. case 2 %SPLwei_inv
  152. fprintf('Shortest-path length computed with an inv transform \n');
  153. data = distance_wei_floyd(SC,'inv');
  154. case 3 %SPLwei_log
  155. fprintf('Shortest-path length computed with a log transform \n');
  156. data = distance_wei_floyd(SC,'log');
  157. case 4 %SPLdist
  158. fprintf('Shortest-path length computed with no transform \n');
  159. data = distance_wei_floyd(SC);
  160. case 5 %SIbin
  161. fprintf('Search Information of binary shortest-paths \n');
  162. data = search_information(double(SC>0));
  163. data = data + data';
  164. case 6 %SIwei_inv
  165. fprintf('Search Information of shortest-paths computed with an inv transform \n');
  166. data = search_information(SC,'inv');
  167. data = data + data';
  168. case 7 %SIwei_log
  169. fprintf('Search Information of shortest-paths computed with a log transform \n');
  170. data = search_information(SC,'log');
  171. data = data + data';
  172. case 8 %SIdist
  173. fprintf('Search Information of shortest-paths computed with no transform \n');
  174. data = search_information(SC);
  175. data = data + data';
  176. case 9 %T
  177. fprintf('Path Transitivity \n');
  178. data = path_transitivity(double(SC>0));
  179. case 10 %deltaMFPT
  180. fprintf('Column-wise z-scored mean first passage time \n');
  181. mfpt = mean_first_passage_time(SC);
  182. deltamfpt = zscore(mfpt,[],1);
  183. data = deltamfpt+deltamfpt';
  184. case 11 %neighOverlap
  185. fprintf('Neighborhood Overlap \n');
  186. data = double(SC>0) * double(SC>0)';
  187. case 12 %MI
  188. fprintf('Matching Index \n');
  189. data = matching_ind(SC);
  190. otherwise
  191. error('This is not an accepted predictor. See list of available predictors \n')
  192. end
  193. pred_data(:,ind2start+v) = data(indx);
  194. end
  195. else
  196. if size(pred_var,1) == length(indx)
  197. pred_data = [pred_data,pred_var];
  198. else
  199. error('Custom predictors must be provided as KxM array of M predictors \n');
  200. end
  201. end
  202. pred_data = x2fx(pred_data,model);
  203. if size(pred_data,2) == size(beta,1)
  204. Y = pred_data*beta;
  205. FCpre = zeros(N);
  206. FCpre(indx) = Y;
  207. FCpre = FCpre+FCpre';
  208. end
  209. if nargin == 6 && ~isempty(FC)
  210. flag_nan_corr = false;
  211. [n1,n2] = size(FC);
  212. if n1 == n2 && n1 == N
  213. % square FC matrix
  214. FCemp = FC(indx);
  215. elseif n1 == length(indx) && n2 == 1
  216. % FC is already an upper-triangle vector
  217. FCemp = FC;
  218. else
  219. warning('FC must be square matrix or a vector containing the upper triangle (no diagonal elements) of the square FC matrix \n')
  220. flag_nan_corr = true;
  221. end
  222. if ~flag_nan_corr
  223. Fcorr = corr(Y,FCemp);
  224. else
  225. Fcorr = nan;
  226. end
  227. end