OSCR

When pain becomes self: limbic-default mode network hyperconnectivity predicts microvascular decompression failure in trigeminal neuralgia.

Code ↔ Paper

5 matches between paragraphs of the paper and lines of its authors' code, computed by the harvester (lexical-v1). Click a colored paragraph or line to see its counterpart.

The 5 matches
  1. [1] § Materials and methods › Effect size ranking analysis ↔ 8SVM.m, lines 224–303 · score 0.78 · aTHA, pTHA, Subcortical region, HIP, AMY, CAU
  2. [2] § Results › The prediction model ↔ 8SVM.m, lines 305–445 · score 0.76 · fold cross validation, SVM classification, classification model, connectivity features, trained, AUC
  3. [3] § Materials and methods › Model construction ↔ 8SVM.m, lines 305–445 · score 0.67 · SVM classifier, cross validation, kernel, splits, train, model
  4. [4] § Results › Top 10 connections by effect size and healthy control group position ↔ 8SVM.m, lines 224–303 · score 0.64 · pTHA, cortical regions, AMY, CAU, GP, NAc
  5. [5] § Materials and methods › Model construction ↔ 8SVM.m, lines 488–539 · score 0.51 · confusion matrices, ROC, curve, SVM, AUC, classification

Paper

Loaded from Europe PMC by your browser, not stored by OSCR: doi.org · Europe PMC

The paper is loaded when this pane is shown.

The authors' code

MATLAB · 1,157 lines · 45 KB · CC-BY-4.0 · 5 matches

  1. %% =====================================================================
  2. % Brain Connectivity Group Comparison Analysis + Permutation Test +
  3. % Modeling with Top 10 Effect Size Connections
  4. % =====================================================================
  5. % clear; close all; clc;
  6. %% 1. Parameter Settings
  7. n_permutations = 5000; % Number of permutations (suggested: 1000-10000)
  8. alpha = 0.05; % Significance level
  9. fdr_threshold = 0.05; % FDR correction threshold
  10. %% 2. Load Data
  11. cd('D:\work\data_analysis\TN')
  12. load E_corr_cortex_subcortex_total_r
  13. E_group = corr_cortex_subcortex_r_FDR_all;
  14. load NE_corr_cortex_subcortex_total_r
  15. NE_group = corr_cortex_subcortex_r_FDR_all;
  16. fprintf('=== Brain Connectivity Group Comparison Analysis ===\n');
  17. fprintf('E-group dimensions: %s\n', mat2str(size(E_group)));
  18. fprintf('NE-group dimensions: %s\n', mat2str(size(NE_group)));
  19. %% 3. Data Preprocessing and Validation
  20. % Ensure correct data format
  21. if size(E_group,1) ~= 100 || size(E_group,2) ~= 16 || size(E_group,3) ~= 30
  22. error('Incorrect E_group dimensions, should be 100¡Á16¡Á30');
  23. end
  24. if size(NE_group,1) ~= 100 || size(NE_group,2) ~= 16 || size(NE_group,3) ~= 30
  25. error('Incorrect NE_group dimensions, should be 100¡Á16¡Á30');
  26. end
  27. % Check data validity
  28. if any(isnan(E_group(:))) || any(isinf(E_group(:)))
  29. warning('E_group contains NaN or Inf values');
  30. E_group(isnan(E_group)) = 0;
  31. E_group(isinf(E_group)) = 0;
  32. end
  33. if any(isnan(NE_group(:))) || any(isinf(NE_group(:)))
  34. warning('NE_group contains NaN or Inf values');
  35. NE_group(isnan(NE_group)) = 0;
  36. NE_group(isinf(NE_group)) = 0;
  37. end
  38. %% 4. Extract Connection Strength Vectors and Reshape Data
  39. % Flatten each subject's 100¡Á16 matrix into 1600-dimensional vector
  40. n_cortical = 100; % Number of cortical regions
  41. n_subcortical = 16; % Number of subcortical regions
  42. n_subjects_E = size(E_group, 3);
  43. n_subjects_NE = size(NE_group, 3);
  44. fprintf('Data reshaping:\n');
  45. fprintf('Connections per subject: %d ¡Á %d = %d\n', n_cortical, n_subcortical, n_cortical*n_subcortical);
  46. % Reshape data: each subject as a row, each column as a connection
  47. data_E = zeros(n_subjects_E, n_cortical * n_subcortical);
  48. data_NE = zeros(n_subjects_NE, n_cortical * n_subcortical);
  49. for subj = 1:n_subjects_E
  50. temp = squeeze(E_group(:,:,subj));
  51. data_E(subj, :) = temp(:)';
  52. end
  53. for subj = 1:n_subjects_NE
  54. temp = squeeze(NE_group(:,:,subj));
  55. data_NE(subj, :) = temp(:)';
  56. end
  57. fprintf('E-group data matrix: %s\n', mat2str(size(data_E)));
  58. fprintf('NE-group data matrix: %s\n', mat2str(size(data_NE)));
  59. %% 5. Calculate Group Difference Statistics (Real Data)
  60. fprintf('\n=== Calculating Real Group Differences ===\n');
  61. % Initialize result matrices
  62. real_t_stats = zeros(n_cortical, n_subcortical);
  63. real_p_values = zeros(n_cortical, n_subcortical);
  64. cohens_d = zeros(n_cortical, n_subcortical); % Effect size
  65. % Perform two-sample t-test for each connection
  66. for i = 1:n_cortical
  67. for j = 1:n_subcortical
  68. % Calculate connection index
  69. conn_idx = (i-1)*n_subcortical + j;
  70. % Extract group data for this connection
  71. conn_E = data_E(:, conn_idx);
  72. conn_NE = data_NE(:, conn_idx);
  73. % Two-sample t-test
  74. [~, p, ~, stats] = ttest2(conn_E, conn_NE, 'Vartype', 'unequal');
  75. % Store results
  76. real_t_stats(i, j) = stats.tstat;
  77. real_p_values(i, j) = p;
  78. % Calculate Cohen's d effect size
  79. mean_diff = mean(conn_E) - mean(conn_NE);
  80. pooled_std = sqrt((std(conn_E)^2 + std(conn_NE)^2)/2);
  81. cohens_d(i, j) = mean_diff / pooled_std;
  82. end
  83. end
  84. fprintf('Uncorrected significant connections: %d (p < %.3f)\n', sum(real_p_values(:) < alpha), alpha);
  85. %% 6. Permutation Test
  86. fprintf('\n=== Starting Permutation Test (%d permutations) ===\n', n_permutations);
  87. % Combine all data
  88. all_data = [data_E; data_NE];
  89. n_total = size(all_data, 1);
  90. labels = [ones(n_subjects_E, 1); 2*ones(n_subjects_NE, 1)];
  91. % Initialize permutation distribution
  92. perm_t_stats = zeros(n_cortical, n_subcortical, n_permutations);
  93. perm_max_t = zeros(n_permutations, 1); % Maximum t-value (for FWE correction)
  94. perm_min_t = zeros(n_permutations, 1); % Minimum t-value (two-sided test)
  95. fprintf('Progress: ');
  96. progress_step = round(n_permutations/20);
  97. for perm = 1:n_permutations
  98. % Display progress
  99. if mod(perm, progress_step) == 0
  100. fprintf('%d%% ', round(perm/n_permutations*100));
  101. end
  102. % Randomly permute labels
  103. perm_labels = labels(randperm(n_total));
  104. % Create permuted groups
  105. perm_group1_idx = perm_labels == 1;
  106. perm_group2_idx = perm_labels == 2;
  107. perm_data1 = all_data(perm_group1_idx, :);
  108. perm_data2 = all_data(perm_group2_idx, :);
  109. % Calculate permuted t-statistics
  110. perm_t_matrix = zeros(n_cortical, n_subcortical);
  111. for i = 1:n_cortical
  112. for j = 1:n_subcortical
  113. conn_idx = (i-1)*n_subcortical + j;
  114. conn1 = perm_data1(:, conn_idx);
  115. conn2 = perm_data2(:, conn_idx);
  116. % Calculate t-statistic (simplified version)
  117. mean1 = mean(conn1);
  118. mean2 = mean(conn2);
  119. std1 = std(conn1);
  120. std2 = std(conn2);
  121. n1 = length(conn1);
  122. n2 = length(conn2);
  123. % Two-sample t-statistic
  124. t_stat = (mean1 - mean2) / sqrt(std1^2/n1 + std2^2/n2);
  125. perm_t_matrix(i, j) = t_stat;
  126. end
  127. end
  128. % Store permutation results
  129. perm_t_stats(:,:,perm) = perm_t_matrix;
  130. % Record extreme statistics (for FWE correction)
  131. perm_max_t(perm) = max(abs(perm_t_matrix(:)));
  132. perm_min_t(perm) = min(perm_t_matrix(:));
  133. end
  134. fprintf('Completed!\n');
  135. %% 7. Calculate Permutation Test P-values
  136. fprintf('\n=== Calculating Permutation Test P-values ===\n');
  137. % Initialize results
  138. perm_p_values = zeros(n_cortical, n_subcortical);
  139. fwe_corrected_p = zeros(n_cortical, n_subcortical); % FWE-corrected p-values
  140. % Calculate p-value for each connection
  141. for i = 1:n_cortical
  142. for j = 1:n_subcortical
  143. % Get real t-value
  144. real_t = real_t_stats(i, j);
  145. % Calculate permutation p-value (two-sided test)
  146. if real_t > 0
  147. % For positive t-values: proportion of permutations ¡Ý real t
  148. extreme_count = sum(perm_t_stats(i,j,:) >= real_t);
  149. else
  150. % For negative t-values: proportion of permutations ¡Ü real t
  151. extreme_count = sum(perm_t_stats(i,j,:) <= real_t);
  152. end
  153. perm_p_values(i, j) = (extreme_count + 1) / (n_permutations + 1);
  154. % Calculate FWE-corrected p-value (based on maximum t-statistic)
  155. if real_t > 0
  156. fwe_extreme = sum(perm_max_t >= abs(real_t));
  157. else
  158. fwe_extreme = sum(perm_min_t <= real_t);
  159. end
  160. fwe_corrected_p(i, j) = (fwe_extreme + 1) / (n_permutations + 1);
  161. end
  162. end
  163. %% 8. FDR Correction
  164. fprintf('=== Performing FDR Correction ===\n');
  165. % Flatten p-value matrix for FDR correction
  166. all_perm_p = perm_p_values(:);
  167. all_fdr_p = mafdr(all_perm_p, 'BHFDR', true); % Using Storey's method
  168. % Reshape back to matrix
  169. fdr_corrected_p = reshape(all_fdr_p, n_cortical, n_subcortical);
  170. % Find FDR-corrected significant connections
  171. fdr_significant = fdr_corrected_p < fdr_threshold;
  172. fwe_significant = fwe_corrected_p < alpha;
  173. fprintf('Permutation test significant connections (uncorrected): %d\n', sum(perm_p_values(:) < alpha));
  174. fprintf('FDR-corrected significant connections (q < %.3f): %d\n', fdr_threshold, sum(fdr_significant(:)));
  175. fprintf('FWE-corrected significant connections (p < %.3f): %d\n', alpha, sum(fwe_significant(:)));
  176. %% 9. Find Top 10 Connections by Effect Size
  177. fprintf('\n=== Finding Top 10 Connections by Effect Size ===\n');
  178. % Load cortical region information
  179. fprintf('Loading cortical region information...\n');
  180. roi_data = readtable('Schaefer2018_100Parcels_7Networks_order_FSLMNI152_1mm.Centroid_RAS.csv');
  181. roi_names_raw = roi_data{:, 2};
  182. if isstring(roi_names_raw)
  183. roi_names = cellstr(roi_names_raw);
  184. elseif istable(roi_names_raw) || istimetable(roi_names_raw)
  185. roi_names = table2cell(roi_names_raw);
  186. else
  187. roi_names = roi_names_raw;
  188. end
  189. % Ensure 100x1 cell array
  190. if iscell(roi_names) && size(roi_names, 2) > 1
  191. roi_names = roi_names(:, 1);
  192. end
  193. % Subcortical region names
  194. subcortical_names = {
  195. 'HIP-rh', 'AMY-rh', 'pTHA-rh', 'aTHA-rh', 'NAc-rh', 'GP-rh', 'PUT-rh', 'CAU-rh', ...
  196. 'HIP-lh', 'AMY-lh', 'pTHA-lh', 'aTHA-lh', 'NAc-lh', 'GP-lh', 'PUT-lh', 'CAU-lh'
  197. };
  198. % Find top 10 connections by absolute effect size
  199. all_cohens_d_abs = abs(cohens_d(:));
  200. [~, sorted_indices] = sort(all_cohens_d_abs, 'descend');
  201. % Take only top 10
  202. n_top_conn = min(10, length(sorted_indices));
  203. top_conn_indices = sorted_indices(1:n_top_conn);
  204. % Get detailed information for top 10 connections
  205. top_conn_info = cell(n_top_conn, 7); % Store: cortical index, subcortical index, cortical name, subcortical name, t-value, p-value, effect size
  206. for k = 1:n_top_conn
  207. idx = top_conn_indices(k);
  208. [i, j] = ind2sub([n_cortical, n_subcortical], idx);
  209. % Get region names
  210. if i <= length(roi_names)
  211. cortical_name = roi_names{i};
  212. else
  213. cortical_name = sprintf('Cortical_%d', i);
  214. end
  215. if j <= length(subcortical_names)
  216. subcortical_name = subcortical_names{j};
  217. else
  218. subcortical_name = sprintf('Subcortical_%d', j);
  219. end
  220. % Simplify names for display
  221. cortical_short = strrep(cortical_name, '7Networks_', '');
  222. cortical_short = strrep(cortical_short, '_', ' ');
  223. if length(cortical_short) > 30
  224. cortical_short = [cortical_short(1:27) '...'];
  225. end
  226. subcortical_short = strrep(subcortical_name, '-', ' ');
  227. top_conn_info{k, 1} = i;
  228. top_conn_info{k, 2} = j;
  229. top_conn_info{k, 3} = cortical_short;
  230. top_conn_info{k, 4} = subcortical_short;
  231. top_conn_info{k, 5} = real_t_stats(i, j);
  232. top_conn_info{k, 6} = perm_p_values(i, j);
  233. top_conn_info{k, 7} = cohens_d(i, j);
  234. end
  235. % Display top 10 connections
  236. fprintf('\nTop 10 Connections by Effect Size:\n');
  237. fprintf('Rank\tCortical Region\t\t\t\t\tSubcortical Region\t\tCohen''s d\t\tp-value\n');
  238. fprintf('%s\n', repmat('-', 80, 1));
  239. for k = 1:n_top_conn
  240. fprintf('%2d\t%-35s\t%-15s\t%10.3f\t\t%.6f\n', ...
  241. k, top_conn_info{k,3}, top_conn_info{k,4}, ...
  242. top_conn_info{k,7}, top_conn_info{k,6});
  243. end
  244. %% 10. Classification Modeling with Top 10 Connections
  245. fprintf('\n=== Classification Modeling with Top 10 Connections ===\n');
  246. % Set classification parameters
  247. n_classification_permutations = 100; % Random repetitions for classification
  248. n_folds = 5; % Cross-validation folds
  249. % Prepare feature data
  250. top_conn_features = zeros(n_subjects_E + n_subjects_NE, n_top_conn);
  251. top_conn_labels = [ones(n_subjects_E, 1); zeros(n_subjects_NE, 1)]; % E-group=1, NE-group=0
  252. % Extract features
  253. for k = 1:n_top_conn
  254. i = top_conn_info{k, 1};
  255. j = top_conn_info{k, 2};
  256. conn_idx = (i-1)*n_subcortical + j;
  257. % Extract group data for this connection
  258. top_conn_features(:, k) = [data_E(:, conn_idx); data_NE(:, conn_idx)];
  259. end
  260. fprintf('Feature matrix dimensions: %s\n', mat2str(size(top_conn_features)));
  261. fprintf('Label dimensions: %s\n', mat2str(size(top_conn_labels)));
  262. % Initialize result storage
  263. classification_results = struct();
  264. classification_results.accuracy_all = zeros(n_classification_permutations, 1);
  265. classification_results.auc_all = zeros(n_classification_permutations, 1);
  266. classification_results.feature_importance_all = zeros(n_classification_permutations, n_top_conn);
  267. classification_results.predictions_all = cell(n_classification_permutations, 1);
  268. classification_results.true_labels_all = cell(n_classification_permutations, 1);
  269. classification_results.scores_all = cell(n_classification_permutations, 1);
  270. % Start classification modeling
  271. fprintf('Starting classification modeling (%d random repetitions)...\n', n_classification_permutations);
  272. for perm = 1:n_classification_permutations
  273. if mod(perm, 10) == 0
  274. fprintf(' Processing iteration %d/%d...\n', perm, n_classification_permutations);
  275. end
  276. % Randomly shuffle data
  277. rng(perm); % Set random seed for reproducibility
  278. n_samples = size(top_conn_features, 1);
  279. shuffle_idx = randperm(n_samples);
  280. X_shuffled = top_conn_features(shuffle_idx, :);
  281. y_shuffled = top_conn_labels(shuffle_idx);
  282. % 5-fold cross-validation
  283. cv_indices = crossvalind('Kfold', y_shuffled, n_folds);
  284. fold_accuracy = zeros(n_folds, 1);
  285. fold_predictions = [];
  286. fold_true_labels = [];
  287. fold_scores = [];
  288. fold_feature_importance = zeros(n_folds, n_top_conn);
  289. for fold = 1:n_folds
  290. % Split training and testing sets
  291. test_idx = (cv_indices == fold);
  292. train_idx = ~test_idx;
  293. X_train = X_shuffled(train_idx, :);
  294. y_train = y_shuffled(train_idx);
  295. X_test = X_shuffled(test_idx, :);
  296. y_test = y_shuffled(test_idx);
  297. % Train SVM classifier
  298. try
  299. % Use linear SVM
  300. svm_model = fitcsvm(X_train, y_train, ...
  301. 'KernelFunction', 'linear', ...
  302. 'Standardize', true, ...
  303. 'BoxConstraint', 1);
  304. % Predict
  305. [y_pred, scores] = predict(svm_model, X_test);
  306. % Calculate accuracy
  307. fold_accuracy(fold) = sum(y_pred == y_test) / length(y_test);
  308. % Store prediction results
  309. fold_predictions = [fold_predictions; y_pred];
  310. fold_true_labels = [fold_true_labels; y_test];
  311. fold_scores = [fold_scores; scores(:, 2)]; % Positive class probability scores
  312. % Calculate feature importance (SVM weights)
  313. if isprop(svm_model, 'Beta')
  314. fold_feature_importance(fold, :) = abs(svm_model.Beta)';
  315. else
  316. % Alternative method if weights cannot be obtained directly
  317. fold_feature_importance(fold, :) = rand(1, n_top_conn);
  318. end
  319. catch ME
  320. fprintf('Warning: Error in fold %d: %s\n', fold, ME.message);
  321. fold_accuracy(fold) = 0.5; % Random guessing accuracy
  322. end
  323. end
  324. % Store this iteration's results
  325. classification_results.accuracy_all(perm) = mean(fold_accuracy);
  326. classification_results.predictions_all{perm} = fold_predictions;
  327. classification_results.true_labels_all{perm} = fold_true_labels;
  328. classification_results.scores_all{perm} = fold_scores;
  329. classification_results.feature_importance_all(perm, :) = mean(fold_feature_importance, 1);
  330. % Calculate AUC
  331. try
  332. [~, ~, ~, auc] = perfcurve(fold_true_labels, fold_scores, 1);
  333. classification_results.auc_all(perm) = auc;
  334. catch
  335. classification_results.auc_all(perm) = 0.5;
  336. end
  337. end
  338. % Calculate average performance
  339. mean_accuracy = mean(classification_results.accuracy_all);
  340. std_accuracy = std(classification_results.accuracy_all);
  341. mean_auc = mean(classification_results.auc_all);
  342. std_auc = std(classification_results.auc_all);
  343. mean_feature_importance = mean(classification_results.feature_importance_all, 1);
  344. fprintf('\nClassification Results Statistics:\n');
  345. fprintf(' Average Accuracy: %.3f ¡À %.3f (range: %.3f - %.3f)\n', ...
  346. mean_accuracy, std_accuracy, min(classification_results.accuracy_all), max(classification_results.accuracy_all));
  347. fprintf(' Average AUC: %.3f ¡À %.3f (range: %.3f - %.3f)\n', ...
  348. mean_auc, std_auc, min(classification_results.auc_all), max(classification_results.auc_all));
  349. fprintf(' Chance level: 0.500\n');
  350. % Statistical significance (permutation test)
  351. n_above_chance = sum(classification_results.accuracy_all > 0.5);
  352. classification_p_value = (n_above_chance + 1) / (n_classification_permutations + 1);
  353. fprintf(' Permutation test p-value: %.4f\n', classification_p_value);
  354. % Determine significance
  355. if classification_p_value < 0.05
  356. fprintf(' ? Classification performance significantly above chance level (p < 0.05)\n');
  357. else
  358. fprintf(' ? Classification performance not significantly above chance level (p = %.4f)\n', classification_p_value);
  359. end
  360. %% 11. Visualization of Classification Results
  361. fprintf('\n=== Generating Classification Result Visualizations ===\n');
  362. figure('Position', [100, 100, 1400, 900], 'Name', 'Classification Analysis Results', 'Color', 'white');
  363. % Subplot 1: Accuracy Distribution
  364. subplot(2, 3, 1);
  365. histogram(classification_results.accuracy_all, 20, 'FaceColor', [0.2, 0.6, 0.8], 'EdgeColor', 'none');
  366. hold on;
  367. xline(0.5, 'r--', 'LineWidth', 2, 'Color', [0.8, 0.2, 0.2]);
  368. xline(mean_accuracy, 'k-', 'LineWidth', 2);
  369. xline(mean_accuracy + std_accuracy, 'k:', 'LineWidth', 1.5);
  370. xline(mean_accuracy - std_accuracy, 'k:', 'LineWidth', 1.5);
  371. xlabel('Classification Accuracy', 'FontSize', 12, 'FontWeight', 'bold');
  372. ylabel('Frequency', 'FontSize', 12, 'FontWeight', 'bold');
  373. title(sprintf('Accuracy Distribution (n=%d iterations)', n_classification_permutations), ...
  374. 'FontSize', 14, 'FontWeight', 'bold');
  375. legend('Distribution', 'Chance level', 'Mean', '¡À1 SD', 'Location', 'best', 'FontSize', 10);
  376. grid on;
  377. % Add statistics text
  378. stats_text = sprintf('Mean = %.3f ¡À %.3f\nRange = [%.3f, %.3f]\np = %.4f', ...
  379. mean_accuracy, std_accuracy, min(classification_results.accuracy_all), ...
  380. max(classification_results.accuracy_all), classification_p_value);
  381. text(0.05, 0.95, stats_text, 'Units', 'normalized', ...
  382. 'HorizontalAlignment', 'left', 'VerticalAlignment', 'top', ...
  383. 'FontSize', 11, 'FontWeight', 'bold', ...
  384. 'BackgroundColor', [1, 1, 0.9], 'EdgeColor', 'k', 'Margin', 2);
  385. % Subplot 2: ROC Curve
  386. subplot(2, 3, 2);
  387. % Combine all iteration predictions for ROC
  388. all_true_labels = [];
  389. all_scores = [];
  390. for perm = 1:n_classification_permutations
  391. all_true_labels = [all_true_labels; classification_results.true_labels_all{perm}];
  392. all_scores = [all_scores; classification_results.scores_all{perm}];
  393. end
  394. % Calculate ROC curve
  395. [X_roc, Y_roc, T_roc, AUC_roc] = perfcurve(all_true_labels, all_scores, 1);
  396. % Plot ROC curve
  397. plot(X_roc, Y_roc, 'b-', 'LineWidth', 2);
  398. hold on;
  399. plot([0, 1], [0, 1], 'r--', 'LineWidth', 1.5); % Random line
  400. xlabel('False Positive Rate (FPR)', 'FontSize', 12, 'FontWeight', 'bold');
  401. ylabel('True Positive Rate (TPR)', 'FontSize', 12, 'FontWeight', 'bold');
  402. title(sprintf('Average ROC Curve (AUC = %.3f)', mean_auc), ...
  403. 'FontSize', 14, 'FontWeight', 'bold');
  404. legend(sprintf('SVM (AUC = %.3f)', mean_auc), 'Random Classifier', ...
  405. 'Location', 'southeast', 'FontSize', 11);
  406. grid on;
  407. axis equal;
  408. xlim([0, 1]);
  409. ylim([0, 1]);
  410. % Subplot 3: Confusion Matrix
  411. subplot(2, 3, 3);
  412. % Calculate average confusion matrix
  413. all_predictions = [];
  414. all_true = [];
  415. for perm = 1:n_classification_permutations
  416. all_predictions = [all_predictions; classification_results.predictions_all{perm}];
  417. all_true = [all_true; classification_results.true_labels_all{perm}];
  418. end
  419. conf_mat = confusionmat(all_true, all_predictions);
  420. conf_mat_normalized = conf_mat ./ sum(conf_mat, 2);
  421. % Plot heatmap
  422. imagesc(conf_mat_normalized);
  423. colorbar;
  424. caxis([0, 1]);
  425. colormap(jet);
  426. % Add numerical labels
  427. for i = 1:2
  428. for j = 1:2
  429. text(j, i, sprintf('%.3f', conf_mat_normalized(i,j)), ...
  430. 'HorizontalAlignment', 'center', 'VerticalAlignment', 'middle', ...
  431. 'FontSize', 14, 'FontWeight', 'bold', 'Color', 'w');
  432. end
  433. end
  434. set(gca, 'XTick', 1:2, 'XTickLabel', {'Predicted E', 'Predicted NE'}, ...
  435. 'YTick', 1:2, 'YTickLabel', {'True E', 'True NE'}, ...
  436. 'FontSize', 12, 'FontWeight', 'bold');
  437. title('Normalized Confusion Matrix (Average)', 'FontSize', 14, 'FontWeight', 'bold');
  438. % Subplot 4: Feature Importance vs Effect Size
  439. subplot(2, 3, 4);
  440. % Sort by feature importance
  441. [sorted_importance, sort_idx] = sort(mean_feature_importance, 'descend');
  442. sorted_names = cell(n_top_conn, 1);
  443. sorted_cohens_d = zeros(n_top_conn, 1);
  444. for k = 1:n_top_conn
  445. idx = sort_idx(k);
  446. sorted_names{k} = sprintf('%s-%s', top_conn_info{idx,3}(1:min(10, length(top_conn_info{idx,3}))), ...
  447. top_conn_info{idx,4}(1:min(5, length(top_conn_info{idx,4}))));
  448. sorted_cohens_d(k) = top_conn_info{idx,7};
  449. end
  450. % Plot double bar chart
  451. x_pos = 1:n_top_conn;
  452. bar_width = 0.35;
  453. bar(x_pos - bar_width/2, sorted_importance, bar_width, ...
  454. 'FaceColor', [0.2, 0.6, 0.8], 'DisplayName', 'Feature Importance');
  455. hold on;
  456. bar(x_pos + bar_width/2, sorted_cohens_d, bar_width, ...
  457. 'FaceColor', [0.8, 0.4, 0.2], 'DisplayName', 'Cohen''s d');
  458. xlabel('Feature Rank', 'FontSize', 12, 'FontWeight', 'bold');
  459. ylabel('Importance / Effect Size', 'FontSize', 12, 'FontWeight', 'bold');
  460. title('Feature Importance vs Effect Size', 'FontSize', 14, 'FontWeight', 'bold');
  461. set(gca, 'XTick', 1:n_top_conn, 'XTickLabel', sorted_names, 'FontSize', 9, 'XTickLabelRotation', 45);
  462. legend('Location', 'best', 'FontSize', 10);
  463. grid on;
  464. % Subplot 5: Group Comparison for Top 3 Features
  465. subplot(2, 3, 5);
  466. % Select top 3 most important features
  467. n_show_features = min(3, n_top_conn);
  468. for k = 1:n_show_features
  469. idx = sort_idx(k);
  470. i = top_conn_info{idx, 1};
  471. j = top_conn_info{idx, 2};
  472. conn_idx = (i-1)*n_subcortical + j;
  473. % Extract data
  474. feature_data_E = data_E(:, conn_idx);
  475. feature_data_NE = data_NE(:, conn_idx);
  476. % Create subplot
  477. subplot(2, 3, 5);
  478. subplot_pos = 0.1 + (k-1)*0.25;
  479. axes('Position', [subplot_pos, 0.15, 0.2, 0.3]);
  480. % Plot boxplot
  481. boxplot([feature_data_E; feature_data_NE], ...
  482. [ones(n_subjects_E,1); 2*ones(n_subjects_NE,1)], ...
  483. 'Labels', {'E Group', 'NE Group'});
  484. hold on;
  485. % Add scatter points
  486. scatter(ones(n_subjects_E,1) + (rand(n_subjects_E,1)-0.5)*0.1, feature_data_E, ...
  487. 30, 'filled', 'MarkerFaceColor', [0.2, 0.4, 0.8], 'MarkerFaceAlpha', 0.6);
  488. scatter(2*ones(n_subjects_NE,1) + (rand(n_subjects_NE,1)-0.5)*0.1, feature_data_NE, ...
  489. 30, 'filled', 'MarkerFaceColor', [0.8, 0.4, 0.2], 'MarkerFaceAlpha', 0.6);
  490. title(sprintf('Feature #%d: %s', k, sorted_names{k}(1:min(15, length(sorted_names{k})))), ...
  491. 'FontSize', 11);
  492. ylabel('Connection Strength', 'FontSize', 10);
  493. grid on;
  494. % Add effect size information
  495. text(1.5, max([feature_data_E; feature_data_NE])*1.05, ...
  496. sprintf('d=%.2f', sorted_cohens_d(k)), ...
  497. 'HorizontalAlignment', 'center', 'FontSize', 10, 'FontWeight', 'bold');
  498. end
  499. % Set main title
  500. axes('Position', [0, 0, 1, 1], 'Visible', 'off');
  501. text(0.5, 0.95, 'Group Comparison for Top 3 Features', ...
  502. 'HorizontalAlignment', 'center', 'FontSize', 14, 'FontWeight', 'bold');
  503. % Subplot 6: Feature Correlation Matrix
  504. subplot(2, 3, 6);
  505. % Calculate feature correlations
  506. feature_corr = corr(top_conn_features);
  507. imagesc(feature_corr);
  508. colorbar;
  509. caxis([-1, 1]);
  510. colormap(jet);
  511. % Add correlation values
  512. for i = 1:n_top_conn
  513. for j = 1:n_top_conn
  514. if i ~= j
  515. text(j, i, sprintf('%.2f', feature_corr(i,j)), ...
  516. 'HorizontalAlignment', 'center', 'VerticalAlignment', 'middle', ...
  517. 'FontSize', 8, 'FontWeight', 'bold', 'Color', 'w');
  518. else
  519. text(j, i, '1.00', ...
  520. 'HorizontalAlignment', 'center', 'VerticalAlignment', 'middle', ...
  521. 'FontSize', 8, 'FontWeight', 'bold', 'Color', 'w');
  522. end
  523. end
  524. end
  525. set(gca, 'XTick', 1:n_top_conn, 'XTickLabel', 1:n_top_conn, ...
  526. 'YTick', 1:n_top_conn, 'YTickLabel', 1:n_top_conn, ...
  527. 'FontSize', 9, 'FontWeight', 'bold');
  528. xlabel('Feature Index', 'FontSize', 12, 'FontWeight', 'bold');
  529. ylabel('Feature Index', 'FontSize', 12, 'FontWeight', 'bold');
  530. title('Feature Correlation Matrix', 'FontSize', 14, 'FontWeight', 'bold');
  531. %% 12. Detailed Results Output and Saving
  532. fprintf('\n=== Saving Detailed Results ===\n');
  533. % Create detailed results structure
  534. detailed_results = struct();
  535. detailed_results.perm_test_results = struct();
  536. detailed_results.perm_test_results.real_t_stats = real_t_stats;
  537. detailed_results.perm_test_results.real_p_values = real_p_values;
  538. detailed_results.perm_test_results.perm_p_values = perm_p_values;
  539. detailed_results.perm_test_results.fdr_corrected_p = fdr_corrected_p;
  540. detailed_results.perm_test_results.fwe_corrected_p = fwe_corrected_p;
  541. detailed_results.perm_test_results.cohens_d = cohens_d;
  542. detailed_results.perm_test_results.significant_fdr = fdr_significant;
  543. detailed_results.perm_test_results.significant_fwe = fwe_significant;
  544. detailed_results.top_connections = struct();
  545. detailed_results.top_connections.n_top = n_top_conn;
  546. detailed_results.top_connections.indices = top_conn_indices;
  547. detailed_results.top_connections.info = top_conn_info;
  548. detailed_results.top_connections.features = top_conn_features;
  549. detailed_results.top_connections.labels = top_conn_labels;
  550. detailed_results.classification_results = classification_results;
  551. detailed_results.classification_results.mean_accuracy = mean_accuracy;
  552. detailed_results.classification_results.std_accuracy = std_accuracy;
  553. detailed_results.classification_results.mean_auc = mean_auc;
  554. detailed_results.classification_results.std_auc = std_auc;
  555. detailed_results.classification_results.mean_feature_importance = mean_feature_importance;
  556. detailed_results.classification_results.p_value = classification_p_value;
  557. % Save results
  558. save('complete_analysis_results.mat', 'detailed_results');
  559. fprintf('Detailed results saved to complete_analysis_results.mat\n');
  560. % Save top 10 connections table
  561. top_conn_table = cell2table(top_conn_info, ...
  562. 'VariableNames', {'Cortical_Index', 'Subcortical_Index', 'Cortical_Name', ...
  563. 'Subcortical_Name', 't_stat', 'p_value', 'Cohens_d'});
  564. writetable(top_conn_table, 'top_10_connections.csv');
  565. fprintf('Top 10 connections information saved to top_10_connections.csv\n');
  566. % Save classification results
  567. classification_summary = table();
  568. classification_summary.Metric = {'Mean_Accuracy'; 'Accuracy_SD'; 'Mean_AUC'; 'AUC_SD'; 'Permutation_p_value'};
  569. classification_summary.Value = [mean_accuracy; std_accuracy; mean_auc; std_auc; classification_p_value];
  570. writetable(classification_summary, 'classification_summary.csv');
  571. fprintf('Classification summary saved to classification_summary.csv\n');
  572. %% 13. Final Summary Report
  573. fprintf('\n========== FINAL ANALYSIS SUMMARY ==========\n');
  574. fprintf('Dataset Information:\n');
  575. fprintf(' E-group subjects: %d\n', n_subjects_E);
  576. fprintf(' NE-group subjects: %d\n', n_subjects_NE);
  577. fprintf(' Total connections: %d ¡Á %d = %d\n', n_cortical, n_subcortical, n_cortical*n_subcortical);
  578. fprintf('\nPermutation Test Results:\n');
  579. fprintf(' Permutations: %d\n', n_permutations);
  580. fprintf(' FDR-significant connections: %d\n', sum(fdr_significant(:)));
  581. fprintf(' Maximum effect size (|Cohen''s d|): %.3f\n', max(abs(cohens_d(:))));
  582. fprintf('\nTop 10 Connections by Effect Size:\n');
  583. for k = 1:min(5, n_top_conn)
  584. fprintf(' %d. %s - %s (d=%.3f, p=%.4f)\n', ...
  585. k, top_conn_info{k,3}, top_conn_info{k,4}, ...
  586. top_conn_info{k,7}, top_conn_info{k,6});
  587. end
  588. fprintf('\nClassification Modeling Results:\n');
  589. fprintf(' Random repetitions: %d\n', n_classification_permutations);
  590. fprintf(' Cross-validation folds: %d\n', n_folds);
  591. fprintf(' Mean accuracy: %.3f ¡À %.3f\n', mean_accuracy, std_accuracy);
  592. fprintf(' Mean AUC: %.3f ¡À %.3f\n', mean_auc, std_auc);
  593. fprintf(' Permutation test p-value: %.4f\n', classification_p_value);
  594. if classification_p_value < 0.05
  595. fprintf(' ¡ú Classification performance is SIGNIFICANTLY above chance level!\n');
  596. else
  597. fprintf(' ¡ú Classification performance is NOT SIGNIFICANT\n');
  598. end
  599. fprintf('\n========== ANALYSIS COMPLETED! ==========\n');
  600. fprintf
  601. %% =====================================================================
  602. %% 13. Final Summary Report
  603. fprintf('\n========== FINAL ANALYSIS SUMMARY ==========\n');
  604. fprintf('Dataset Information:\n');
  605. fprintf(' E-group subjects: %d\n', n_subjects_E);
  606. fprintf(' NE-group subjects: %d\n', n_subjects_NE);
  607. fprintf(' Total connections: %d ¡Á %d = %d\n', n_cortical, n_subcortical, n_cortical*n_subcortical);
  608. fprintf('\nPermutation Test Results:\n');
  609. fprintf(' Permutations: %d\n', n_permutations);
  610. fprintf(' FDR-significant connections: %d\n', sum(fdr_significant(:)));
  611. fprintf(' Maximum effect size (|Cohen''s d|): %.3f\n', max(abs(cohens_d(:))));
  612. fprintf('\nTop 10 Connections by Effect Size:\n');
  613. for k = 1:min(5, n_top_conn)
  614. fprintf(' %d. %s - %s (d=%.3f, p=%.4f)\n', ...
  615. k, top_conn_info{k,3}, top_conn_info{k,4}, ...
  616. top_conn_info{k,7}, top_conn_info{k,6});
  617. end
  618. fprintf('\nClassification Modeling Results:\n');
  619. fprintf(' Random repetitions: %d\n', n_classification_permutations);
  620. fprintf(' Cross-validation folds: %d\n', n_folds);
  621. fprintf(' Mean accuracy: %.3f ¡À %.3f\n', mean_accuracy, std_accuracy);
  622. fprintf(' Mean AUC: %.3f ¡À %.3f\n', mean_auc, std_auc);
  623. fprintf(' Permutation test p-value: %.4f\n', classification_p_value);
  624. if classification_p_value < 0.05
  625. fprintf(' ¡ú Classification performance is SIGNIFICANTLY above chance level!\n');
  626. else
  627. fprintf(' ¡ú Classification performance is NOT SIGNIFICANT\n');
  628. end
  629. fprintf('\n========== ANALYSIS COMPLETED! ==========\n');
  630. % ɾ³ý»ò×¢Ê͵ôÏÂÃæÕâÐÐ
  631. % fprintf
  632. %% =====================================================================
  633. % ÐÂÔö²¿·Ö£º±£´æ·ÖÀà·ÖÎöͼÏñΪ¸ßÖÊÁ¿Ê¸Á¿Í¼£¨±£´æµ½Vector_FiguresÎļþ¼Ð£©
  634. %% 13. Final Summary Report
  635. fprintf('\n========== FINAL ANALYSIS SUMMARY ==========\n');
  636. fprintf('Dataset Information:\n');
  637. fprintf(' E-group subjects: %d\n', n_subjects_E);
  638. fprintf(' NE-group subjects: %d\n', n_subjects_NE);
  639. fprintf(' Total connections: %d ¡Á %d = %d\n', n_cortical, n_subcortical, n_cortical*n_subcortical);
  640. fprintf('\nPermutation Test Results:\n');
  641. fprintf(' Permutations: %d\n', n_permutations);
  642. fprintf(' FDR-significant connections: %d\n', sum(fdr_significant(:)));
  643. fprintf(' Maximum effect size (|Cohen''s d|): %.3f\n', max(abs(cohens_d(:))));
  644. fprintf('\nTop 10 Connections by Effect Size:\n');
  645. for k = 1:min(5, n_top_conn)
  646. fprintf(' %d. %s - %s (d=%.3f, p=%.4f)\n', ...
  647. k, top_conn_info{k,3}, top_conn_info{k,4}, ...
  648. top_conn_info{k,7}, top_conn_info{k,6});
  649. end
  650. fprintf('\nClassification Modeling Results:\n');
  651. fprintf(' Random repetitions: %d\n', n_classification_permutations);
  652. fprintf(' Cross-validation folds: %d\n', n_folds);
  653. fprintf(' Mean accuracy: %.3f ¡À %.3f\n', mean_accuracy, std_accuracy);
  654. fprintf(' Mean AUC: %.3f ¡À %.3f\n', mean_auc, std_auc);
  655. fprintf(' Permutation test p-value: %.4f\n', classification_p_value);
  656. if classification_p_value < 0.05
  657. fprintf(' ¡ú Classification performance is SIGNIFICANTLY above chance level!\n');
  658. else
  659. fprintf(' ¡ú Classification performance is NOT SIGNIFICANT\n');
  660. end
  661. fprintf('\n========== ANALYSIS COMPLETED! ==========\n');
  662. % ɾ³ý»ò×¢Ê͵ôÏÂÃæÕâÐÐ
  663. % fprintf
  664. %% =====================================================================
  665. % ±£´æÍ¼Ïñ²¿·Ö´ÓÕâÀ↑ʼ
  666. % =====================================================================
  667. fprintf('\n========================================\n');
  668. fprintf('Saving classification analysis figures as vector graphics...\n');
  669. fprintf('========================================\n');
  670. % ´´½¨±£´æÍ¼ÏñµÄÎļþ¼Ð
  671. output_folder = 'Vector_Figures';
  672. if ~exist(output_folder, 'dir')
  673. mkdir(output_folder);
  674. end
  675. % ÔÚVector_FiguresÏ´´½¨·ÖÀà½á¹ûµÄ×ÓÎļþ¼Ð
  676. classification_subfolder = fullfile(output_folder, 'Classification_Results');
  677. if ~exist(classification_subfolder, 'dir')
  678. mkdir(classification_subfolder);
  679. end
  680. % »ñÈ¡µ±Ç°Ê±¼ä´Á
  681. timestamp = datestr(now, 'yyyymmdd_HHMMSS');
  682. % ¶¨ÒåÒª±£´æµÄfigure
  683. figure_info = {
  684. 1, 'Classification_Analysis_Results';
  685. };
  686. % ÉèÖÃͼÐÎÊôÐÔ
  687. set(0, 'DefaultAxesFontName', 'Arial');
  688. set(0, 'DefaultTextFontName', 'Arial');
  689. % ±£´æÖ÷ͼ
  690. for i = 1:size(figure_info, 1)
  691. fig_num = figure_info{i, 1};
  692. fig_name = figure_info{i, 2};
  693. if ishandle(fig_num)
  694. figure(fig_num);
  695. set(gcf, 'PaperPositionMode', 'auto');
  696. set(gcf, 'InvertHardcopy', 'off');
  697. set(gcf, 'Renderer', 'painters');
  698. fprintf('\nSaving Figure %d: %s\n', fig_num, fig_name);
  699. % ±£´æÎªPDF
  700. pdf_filename = fullfile(classification_subfolder, sprintf('%s_%s.pdf', fig_name, timestamp));
  701. try
  702. exportgraphics(gcf, pdf_filename, 'ContentType', 'vector');
  703. fprintf(' ? Saved PDF: %s\n', pdf_filename);
  704. catch
  705. print(gcf, pdf_filename, '-dpdf', '-r600');
  706. fprintf(' ? Saved PDF (print): %s\n', pdf_filename);
  707. end
  708. % ±£´æÎªEPS
  709. eps_filename = fullfile(classification_subfolder, sprintf('%s_%s.eps', fig_name, timestamp));
  710. print(gcf, eps_filename, '-depsc', '-r600');
  711. fprintf(' ? Saved EPS: %s\n', eps_filename);
  712. % ±£´æÎªPNG
  713. png_filename = fullfile(classification_subfolder, sprintf('%s_%s.png', fig_name, timestamp));
  714. print(gcf, png_filename, '-dpng', '-r300');
  715. fprintf(' ? Saved PNG: %s\n', png_filename);
  716. end
  717. end
  718. fprintf('\n========================================\n');
  719. fprintf('All figures saved to: %s\n', classification_subfolder);
  720. fprintf('========================================\n');
  721. %% 13. Final Summary Report
  722. fprintf('\n========== FINAL ANALYSIS SUMMARY ==========\n');
  723. fprintf('Dataset Information:\n');
  724. fprintf(' E-group subjects: %d\n', n_subjects_E);
  725. fprintf(' NE-group subjects: %d\n', n_subjects_NE);
  726. fprintf(' Total connections: %d ¡Á %d = %d\n', n_cortical, n_subcortical, n_cortical*n_subcortical);
  727. fprintf('\nPermutation Test Results:\n');
  728. fprintf(' Permutations: %d\n', n_permutations);
  729. fprintf(' FDR-significant connections: %d\n', sum(fdr_significant(:)));
  730. fprintf(' Maximum effect size (|Cohen''s d|): %.3f\n', max(abs(cohens_d(:))));
  731. fprintf('\nTop 10 Connections by Effect Size:\n');
  732. for k = 1:min(5, n_top_conn)
  733. fprintf(' %d. %s - %s (d=%.3f, p=%.4f)\n', ...
  734. k, top_conn_info{k,3}, top_conn_info{k,4}, ...
  735. top_conn_info{k,7}, top_conn_info{k,6});
  736. end
  737. fprintf('\nClassification Modeling Results:\n');
  738. fprintf(' Random repetitions: %d\n', n_classification_permutations);
  739. fprintf(' Cross-validation folds: %d\n', n_folds);
  740. fprintf(' Mean accuracy: %.3f ¡À %.3f\n', mean_accuracy, std_accuracy);
  741. fprintf(' Mean AUC: %.3f ¡À %.3f\n', mean_auc, std_auc);
  742. fprintf(' Permutation test p-value: %.4f\n', classification_p_value);
  743. if classification_p_value < 0.05
  744. fprintf(' ¡ú Classification performance is SIGNIFICANTLY above chance level!\n');
  745. else
  746. fprintf(' ¡ú Classification performance is NOT SIGNIFICANT\n');
  747. end
  748. fprintf('\n========== ANALYSIS COMPLETED! ==========\n');
  749. % ɾ³ý»ò×¢Ê͵ôÏÂÃæÕâÐÐ
  750. % fprintf
  751. %% =====================================================================
  752. % ±£´æÍ¼Ïñ²¿·Ö - ±£´æµ½ vector_figures Îļþ¼Ð
  753. % =====================================================================
  754. fprintf('\n========================================\n');
  755. fprintf('Saving classification analysis figures to vector_figures folder...\n');
  756. fprintf('========================================\n');
  757. % ´´½¨±£´æÍ¼ÏñµÄÎļþ¼Ð£¨Ê¹ÓÃСд vector_figures£©
  758. output_folder = 'vector_figures';
  759. if ~exist(output_folder, 'dir')
  760. mkdir(output_folder);
  761. fprintf('Created folder: %s\n', output_folder);
  762. end
  763. % ÔÚvector_figuresÏ´´½¨·ÖÀà½á¹ûµÄ×ÓÎļþ¼Ð
  764. classification_subfolder = fullfile(output_folder, 'Classification_Results');
  765. if ~exist(classification_subfolder, 'dir')
  766. mkdir(classification_subfolder);
  767. fprintf('Created subfolder: %s\n', classification_subfolder);
  768. end
  769. % »ñÈ¡µ±Ç°Ê±¼ä´Á
  770. timestamp = datestr(now, 'yyyymmdd_HHMMSS');
  771. % ¶¨ÒåÒª±£´æµÄfigure
  772. figure_info = {
  773. 1, 'Classification_Analysis_Results';
  774. };
  775. % ÉèÖÃͼÐÎÊôÐÔ
  776. set(0, 'DefaultAxesFontName', 'Arial');
  777. set(0, 'DefaultTextFontName', 'Arial');
  778. % ±£´æÖ÷ͼ
  779. for i = 1:size(figure_info, 1)
  780. fig_num = figure_info{i, 1};
  781. fig_name = figure_info{i, 2};
  782. if ishandle(fig_num)
  783. figure(fig_num);
  784. set(gcf, 'PaperPositionMode', 'auto');
  785. set(gcf, 'InvertHardcopy', 'off');
  786. set(gcf, 'Renderer', 'painters');
  787. fprintf('\nSaving Figure %d: %s\n', fig_num, fig_name);
  788. % 1. ±£´æÎªPDF£¨Ê¸Á¿¸ñʽ£¬×îÊʺϲåÈëÂÛÎÄ£©
  789. pdf_filename = fullfile(classification_subfolder, sprintf('%s_%s.pdf', fig_name, timestamp));
  790. try
  791. exportgraphics(gcf, pdf_filename, 'ContentType', 'vector');
  792. fprintf(' ? Saved PDF (vector): %s\n', pdf_filename);
  793. catch
  794. print(gcf, pdf_filename, '-dpdf', '-r600');
  795. fprintf(' ? Saved PDF (print): %s\n', pdf_filename);
  796. end
  797. % 2. ±£´æÎªEPS£¨Ê¸Á¿¸ñʽ£¬ÊʺÏLaTeX£©
  798. eps_filename = fullfile(classification_subfolder, sprintf('%s_%s.eps', fig_name, timestamp));
  799. print(gcf, eps_filename, '-depsc', '-r600');
  800. fprintf(' ? Saved EPS (vector): %s\n', eps_filename);
  801. % 3. ±£´æÎªTIFF£¨¸ß·Ö±æÂÊ£¬ÊÊºÏÆÚ¿¯Í¶¸å£©
  802. tiff_filename = fullfile(classification_subfolder, sprintf('%s_%s_600dpi.tiff', fig_name, timestamp));
  803. print(gcf, tiff_filename, '-dtiff', '-r600');
  804. fprintf(' ? Saved TIFF (600 DPI): %s\n', tiff_filename);
  805. % 4. ±£´æÎªPNG£¨¸ß·Ö±æÂÊ£¬ÊʺϿìËÙÔ¤ÀÀ£©
  806. png_filename = fullfile(classification_subfolder, sprintf('%s_%s_600dpi.png', fig_name, timestamp));
  807. print(gcf, png_filename, '-dpng', '-r600');
  808. fprintf(' ? Saved PNG (600 DPI): %s\n', png_filename);
  809. % 5. ±£´æÎªJPEG£¨Ñ¹Ëõ¸ñʽ£¬ÊʺÏÍøÒ³£©
  810. jpg_filename = fullfile(classification_subfolder, sprintf('%s_%s_300dpi.jpg', fig_name, timestamp));
  811. print(gcf, jpg_filename, '-djpeg', '-r300');
  812. fprintf(' ? Saved JPEG (300 DPI): %s\n', jpg_filename);
  813. end
  814. end
  815. % ¶îÍâ±£´æ£º½«Figure 1µÄÿ¸ö×Óͼµ¥¶À±£´æ
  816. if ishandle(1)
  817. figure(1);
  818. % »ñÈ¡µ±Ç°figureµÄËùÓÐaxes
  819. all_axes = findall(gcf, 'Type', 'axes');
  820. subplot_counter = 0;
  821. subplot_names = {'01_Accuracy_Distribution', '02_ROC_Curve', '03_Confusion_Matrix', ...
  822. '04_Feature_Importance', '05_Group_Comparison', '06_Correlation_Matrix'};
  823. for ax_idx = 1:length(all_axes)
  824. % Ìø¹ýcolorbarºÍlegend
  825. ax_tag = get(all_axes(ax_idx), 'Tag');
  826. if ~isempty(ax_tag) && (strcmp(ax_tag, 'colorbar') || strcmp(ax_tag, 'legend') || strcmp(ax_tag, 'annotation'))
  827. continue;
  828. end
  829. % »ñÈ¡axesµÄλÖÃ
  830. ax_pos = get(all_axes(ax_idx), 'Position');
  831. % Ö»±£´æÖ÷ÒªµÄ×Óͼ
  832. if ax_pos(1) > 0.02 && ax_pos(1) < 0.98 && ax_pos(2) > 0.02 && ax_pos(2) < 0.98
  833. subplot_counter = subplot_counter + 1;
  834. % ´´½¨ÐµÄfigure
  835. single_fig = figure('Visible', 'off', 'Position', [100, 100, 500, 400], ...
  836. 'Color', 'white', 'Renderer', 'painters');
  837. % ¸´ÖÆaxesÄÚÈÝ
  838. new_ax = copyobj(all_axes(ax_idx), single_fig);
  839. set(new_ax, 'Position', [0.13, 0.11, 0.775, 0.815]);
  840. % ÉèÖÃ×ÓͼÃû³Æ
  841. if subplot_counter <= length(subplot_names)
  842. subplot_name = subplot_names{subplot_counter};
  843. else
  844. subplot_name = sprintf('Subplot_%02d', subplot_counter);
  845. end
  846. % ±£´æµ¥¸ö×ÓͼΪPDF
  847. subplot_pdf = fullfile(classification_subfolder, sprintf('%s_%s.pdf', subplot_name, timestamp));
  848. try
  849. exportgraphics(single_fig, subplot_pdf, 'ContentType', 'vector');
  850. fprintf(' ? Saved subplot %d as PDF: %s\n', subplot_counter, subplot_pdf);
  851. catch
  852. print(single_fig, subplot_pdf, '-dpdf', '-r600');
  853. end
  854. % ±£´æµ¥¸ö×ÓͼΪTIFF
  855. subplot_tiff = fullfile(classification_subfolder, sprintf('%s_%s_600dpi.tiff', subplot_name, timestamp));
  856. print(single_fig, subplot_tiff, '-dtiff', '-r600');
  857. fprintf(' ? Saved subplot %d as TIFF: %s\n', subplot_counter, subplot_tiff);
  858. % ±£´æµ¥¸ö×ÓͼΪPNG
  859. subplot_png = fullfile(classification_subfolder, sprintf('%s_%s.png', subplot_name, timestamp));
  860. print(single_fig, subplot_png, '-dpng', '-r300');
  861. close(single_fig);
  862. end
  863. end
  864. fprintf('\n ? %d individual subplots saved in multiple formats\n', subplot_counter);
  865. end
  866. % ±£´æÉèÖÃÐÅÏ¢
  867. settings_file = fullfile(classification_subfolder, sprintf('Figure_Settings_%s.txt', timestamp));
  868. fid = fopen(settings_file, 'w');
  869. fprintf(fid, 'Classification Analysis Figure Export Settings\n');
  870. fprintf(fid, '==============================================\n');
  871. fprintf(fid, 'Date: %s\n', datestr(now));
  872. fprintf(fid, 'MATLAB Version: %s\n', version);
  873. fprintf(fid, 'Output Folder: %s\n', classification_subfolder);
  874. fprintf(fid, 'Renderer: painters\n');
  875. fprintf(fid, 'Resolutions: PDF/vector, EPS/vector, TIFF 600 DPI, PNG 600 DPI, JPEG 300 DPI\n');
  876. fprintf(fid, 'Font: Arial\n');
  877. fprintf(fid, '\nAnalysis Summary:\n');
  878. fprintf(fid, 'Classification Results:\n');
  879. fprintf(fid, ' Mean Accuracy: %.3f ¡À %.3f\n', mean_accuracy, std_accuracy);
  880. fprintf(fid, ' Mean AUC: %.3f ¡À %.3f\n', mean_auc, std_auc);
  881. fprintf(fid, ' Permutation p-value: %.4f\n', classification_p_value);
  882. fprintf(fid, ' Significant: %s\n', string(classification_p_value < 0.05));
  883. fclose(fid);
  884. fprintf('\n========================================\n');
  885. fprintf('All figures saved to: %s\n', classification_subfolder);
  886. fprintf('Settings file saved: %s\n', settings_file);
  887. fprintf('========================================\n');
  888. % ÏÔʾ±£´æµÄÎļþÁбí
  889. fprintf('\nSaved files in %s:\n', classification_subfolder);
  890. files = dir(fullfile(classification_subfolder, '*'));
  891. file_count = 0;
  892. tiff_count = 0;
  893. pdf_count = 0;
  894. eps_count = 0;
  895. png_count = 0;
  896. jpg_count = 0;
  897. for i = 1:length(files)
  898. if ~files(i).isdir
  899. file_count = file_count + 1;
  900. file_size = files(i).bytes;
  901. if file_size < 1024
  902. size_str = sprintf('%d B', file_size);
  903. elseif file_size < 1024^2
  904. size_str = sprintf('%.2f KB', file_size/1024);
  905. else
  906. size_str = sprintf('%.2f MB', file_size/(1024^2));
  907. end
  908. fprintf(' - %s (%s)\n', files(i).name, size_str);
  909. % ͳ¼Æ²»Í¬¸ñʽÎļþÊýÁ¿
  910. [~, ~, ext] = fileparts(files(i).name);
  911. switch lower(ext)
  912. case '.tiff'
  913. tiff_count = tiff_count + 1;
  914. case '.pdf'
  915. pdf_count = pdf_count + 1;
  916. case '.eps'
  917. eps_count = eps_count + 1;
  918. case '.png'
  919. png_count = png_count + 1;
  920. case '.jpg'
  921. jpg_count = jpg_count + 1;
  922. end
  923. end
  924. end
  925. fprintf('\nFile format summary:\n');
  926. fprintf(' PDF files: %d (vector)\n', pdf_count);
  927. fprintf(' EPS files: %d (vector)\n', eps_count);
  928. fprintf(' TIFF files: %d (600 DPI)\n', tiff_count);
  929. fprintf(' PNG files: %d (600/300 DPI)\n', png_count);
  930. fprintf(' JPEG files: %d (300 DPI)\n', jpg_count);
  931. fprintf(' Total: %d files\n', file_count);
  932. fprintf('\n');
  933. % ´ò¿ª±£´æµÄÎļþ¼Ð
  934. try
  935. winopen(classification_subfolder);
  936. fprintf('Opened folder: %s\n', classification_subfolder);
  937. catch
  938. fprintf('Files saved to: %s\n', fullfile(pwd, classification_subfolder));
  939. end

8SVM.m, under CC-BY-4.0 · at the source

Overview

Authors: Ying Wang1,2,3, Chenglong Cao1,4, Hao Chen5, Min Wu1, Xiaosong He6, Xiaofeng Jiang1
ORCID iDs: Xiaosong He
  1. Department of Neurosurgery, The First Affiliated Hospital of USTC, Division of Life Sciences and Medicine, University of Science and Technology of China, Hefei, Anhui Province 230001, P. R. China
  2. Anhui Provincial Stereotactic Neurosurgical Institute, Hefei, Anhui Province 230001, P. R. China
  3. Anhui Province Key Laboratory of Brain Function and Brain Disease, Hefei, Anhui Province 230001, P. R. China
  4. MRC Brain Networks Dynamics Unit, University of Oxford, Oxford, UK
  5. Department of Radiology, The First Affiliated Hospital of USTC, Division of Life Sciences and Medicine, University of Science and Technology of China, Hefei, Anhui 230001, China
  6. Department of Psychology, University of Science and Technology of China, Hefei, Anhui Province 230026, China
Journal: Brain communications, volume 8, issue 3, article fcag220
Dates: received 26 February 2026; accepted 9 June 2026; published online 11 June 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI 10.1093/braincomms/fcag220 · PMID 42327366 · PMCID PMC13281923 · OpenAlex W7164311646
Open access: gold, a free copy (OpenAlex)
Status: code verified
Categories: structural MRI / diffusion (modality), fMRI (modality), human (organism), pain (population), systems (subfield)
Methods: Statistics, Machine learning, Connectivity, fMRI & imaging
Keywords: trigeminal neuralgia, microvascular decompression, pain embedding, default mode network, functional connectivity
Topic: Trigeminal Neuralgia and Treatments (Pathology and Forensic Medicine, Medicine), according to OpenAlex
Funding: University of Science and Technology of China; Double First-Class Initiative (YD9110002096); Anhui Provincial Health and Wellness Research Projects (AHWJ2024Aa30440)
Citations: not cited yet (Europe PMC); 35 references in the paper

Abstract

Microvascular decompression is the standard surgical intervention for classical trigeminal neuralgia attributed to NVC. However, up to 30% of patients experience poor outcomes despite technically successful surgery, suggesting non-peripheral mechanisms. This study investigates whether central neural reorganization—manifested as altered cortico-subcortical connectivity and white matter microstructure—underlies poor surgical outcomes in patients with ‘incidental’ low-pressure vascular contact. In this prospective nested case-control study, we enrolled 60 patients with medication-refractory classical trigeminal neuralgia who underwent microvascular decompression and 30 matched healthy controls. Based on the 3-month surgical outcome, patients were retrospectively stratified into effective and ineffective groups. All participants underwent preoperative resting-state functional MRI and diffusion tensor imaging. Whole-brain functional connectivity between 100 cortical (Schaefer atlas) and 16 subcortical (Tian atlas) regions was analysed. Connections were ranked by between-group effect size (Cohen’s d); the top 10 were used to train a SVM classifier. Correlational tractography assessed the relationship between fractional anisotropy and disease duration. Despite comparable preoperative pain, the ineffective group had significantly lower intraoperative vascular pressure (P = 0.02). Compared to the effective group, the ineffective group exhibited significantly enhanced functional connectivity between default mode, somatomotor and control networks and subcortical limbic structures (amygdala, nucleus accumbens, hippocampus) (P < 0.05, permutation test). A SVM classifier trained on these features achieved 86.0% accuracy (AUC = 0.931) in distinguishing outcome groups. Diffusion tensor imaging analysis revealed that longer disease duration was associated with decreased fractional anisotropy in sensorimotor white matter tracts, indicating progressive microstructural decline. Poor surgical outcome is not merely ineffective decompression, but a signature of maladaptive central reorganization—specifically, heightened default mode network–limbic coupling. This hyperconnectivity indicates that pain has become cognitively and affectively ‘self-embedded’, transitioning from a sensory event to a persistent self-referential narrative that sustains pain even after peripheral trigger removal. These results reframe a subset of trigeminal neuralgia as a central network disorder of pain self-representation and identify default mode network–amygdala hyperconnectivity as a candidate target for circuit-based neuromodulation—such as repetitive transcranial magnetic stimulation over medial prefrontal hubs—to ‘unlearn’ the embedded pain trace, either adjunctively or as an alternative to microvascular decompression.

Reproduced under the paper's license (CC BY), from the paper cited above.

Repository

Its files are read in the Code ↔ Paper reader above, with 5 matches between paragraphs and lines of code.

Zenodo 19106465

License: CC-BY-4.0
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Languages: MATLAB (4), Shell (4)
Size: 8 files, 8 scripts
Software Heritage: not checked
Found in: “Data availability”
Not found: README, license file, CITATION.cff, environment file, tests, continuous integration, documentation
Tools: Statistics and Machine Learning Toolbox (2 files), AFNI (1 file), Dcm2Bids (1 file), fMRIPrep (1 file), FSL (1 file)
Availability: 1 check, the latest on 27 September 2026: the link answers (HTTP 200)
  • 27 September 2026: the link answers (HTTP 200)
8 files

The paper's code and data availability statement is in the Data section.

Tracing map

Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.

What the map holds:

  • 1 repository of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 8 scripts, each with its path and the digest of its content;
  • 5 matches between paragraphs of the paper and lines of the code (method lexical-v1);
  • neither the text of the paper nor the code itself.

Its JSON (tracing-map.json) is deposited on Zenodo with its DOI once the map is validated.

Data

No dataset and no data link were found in the paper.

Data availability

The datasets used and/or analysed during the current study are available from the corresponding author on reasonable request. All custom MATLAB scripts used for data analysis have been deposited in Zenodo (DOI:10.5281/zenodo.19106465 (https://doi.org/10.5281/zenodo.19106465)) and are publicly available at https://zenodo.org/records/19106465.

Reproduced under the paper's license (CC BY), from the paper cited above.

Versions

The history of this record: each version stored by the harvester or made by a correction of its authors or of the maintainers of its code, and what changed in its facts. The texts of the paper (its abstract, its availability statements) are not part of it; versions that changed only those are not listed.

Version 1, 27 September 2026: the first record

Recorded: type, language, journal, volume, issue, pages, dates, 6 authors, 5 keywords, 3 funders, 35 references.

Cite

This paper

Wang, Y., Cao, C., Chen, H., Wu, M., He, X., & Jiang, X. (2026). When pain becomes self: limbic-default mode network hyperconnectivity predicts microvascular decompression failure in trigeminal neuralgia. Brain communications, 8(3), fcag220. https://doi.org/10.1093/braincomms/fcag220

BibTeX

@article{wang2026when,
author = {Wang, Ying and Cao, Chenglong and Chen, Hao and Wu, Min and He, Xiaosong and Jiang, Xiaofeng},
title = {{When pain becomes self: limbic-default mode network hyperconnectivity predicts microvascular decompression failure in trigeminal neuralgia}},
journal = {Brain communications},
year = {2026},
month = jun,
volume = {8},
number = {3},
pages = {fcag220},
publisher = {Oxford University Press},
issn = {2632-1297},
doi = {10.1093/braincomms/fcag220},
url = {https://doi.org/10.1093/braincomms/fcag220},
pmid = {42327366},
pmcid = {PMC13281923}
}

RIS

TY - JOUR
AU - Wang, Ying
AU - Cao, Chenglong
AU - Chen, Hao
AU - Wu, Min
AU - He, Xiaosong
AU - Jiang, Xiaofeng
TI - When pain becomes self: limbic-default mode network hyperconnectivity predicts microvascular decompression failure in trigeminal neuralgia
T2 - Brain communications
J2 - Brain Commun
PY - 2026
DA - 2026/06/11
VL - 8
IS - 3
SP - fcag220
SN - 2632-1297
PB - Oxford University Press
DO - 10.1093/braincomms/fcag220
UR - https://doi.org/10.1093/braincomms/fcag220
LA - en
ER -

CSL-JSON

{
"id": "10.1093/braincomms/fcag220",
"type": "article-journal",
"title": "When pain becomes self: limbic-default mode network hyperconnectivity predicts microvascular decompression failure in trigeminal neuralgia",
"container-title": "Brain communications",
"author": [
{
"family": "Wang",
"given": "Ying"
},
{
"family": "Cao",
"given": "Chenglong"
},
{
"family": "Chen",
"given": "Hao"
},
{
"family": "Wu",
"given": "Min"
},
{
"family": "He",
"given": "Xiaosong"
},
{
"family": "Jiang",
"given": "Xiaofeng"
}
],
"container-title-short": "Brain Commun",
"volume": "8",
"issue": "3",
"page": "fcag220",
"DOI": "10.1093/braincomms/fcag220",
"PMID": "42327366",
"PMCID": "PMC13281923",
"ISSN": "2632-1297",
"publisher": "Oxford University Press",
"URL": "https://doi.org/10.1093/braincomms/fcag220",
"language": "en",
"issued": {
"date-parts": [
[
2026,
6,
11
]
]
}
}

The tracing map gets a citation of its own once an author has validated it and it has a DOI.

Similar papers

The papers with a page that share the most with this one: the tools found in their code, their categories, datasets, cited references and authors, the rarest counting most.

[1] doi:10.1162/imag.a.1252 [code]
Does the brain's E:I balance really shape long-range temporal correlations? Lessons learned from 3T MRI.
Journal: Imaging neuroscience (Cambridge, Mass.)
In common: Dcm2Bids, fMRIPrep, AFNI, 1 other tool, fMRI, structural MRI / diffusion, 1 reference
[2] doi:10.1186/s10194-026-02419-7 [code]
Transcriptional correlates of structure-function coupling plasticity in trigeminal neuralgia: unveiling the synaptic and metabolic associations.
Journal: The journal of headache and pain
In common: Statistics and Machine Learning Toolbox, pain, structural MRI / diffusion, 5 references
[3] doi:10.1002/hbm.70621 [code]
Optimising 7T-fMRI for Imaging Regions of Magnetic Susceptibility.
Journal: Human brain mapping
In common: fMRIPrep, AFNI, FSL, 1 other tool, fMRI, 1 reference
[4] doi:10.1093/braincomms/fcag129 [code]
Longitudinal changes of choroid plexus volumes and MRI ratios in multiple sclerosis.
Journal: Brain communications
In common: Dcm2Bids, fMRIPrep, FSL, 1 other tool, structural MRI / diffusion
[5] doi:10.1162/imag.a.1347 [code]
Neural and behavioural correlates of theory of mind reasoning in five-year-old children born preterm.
Journal: Imaging neuroscience (Cambridge, Mass.)
In common: Dcm2Bids, fMRIPrep, FSL, fMRI, 1 reference
[6] doi:10.1016/j.dcn.2026.101765 [code]
Fusiform face area development correlates with development in higher-order social brain regions.
Journal: Developmental cognitive neuroscience
In common: Dcm2Bids, fMRIPrep, FSL, fMRI, 1 reference
[7] doi:10.1162/imag.a.1198 [code]
MEPrep: A robust pipeline for multi-echo fMRI denoising and preprocessing.
Journal: Imaging neuroscience (Cambridge, Mass.)
In common: fMRIPrep, AFNI, FSL, fMRI, 2 references
[8] doi:10.1038/s41467-026-71151-2 [code]
Common and distinct neural correlates of social interaction processing and theory of mind in narratives.
Journal: Nature communications
In common: fMRIPrep, AFNI, FSL, 1 other tool, 1 reference
[9] doi:10.1038/s41467-026-73668-y [code]
Convergent and divergent brain-cognition development in early adolescence.
Journal: Nature communications
In common: AFNI, FSL, Statistics and Machine Learning Toolbox, fMRI, 2 references
[10] doi:10.1016/j.bpsgos.2026.100787 [code]
Dynamic Functional Synchronization Profiles in Autism Differ by Spatial Scale and Along Hierarchical Cortical Gradients.
Journal: Biological psychiatry global open science
In common: AFNI, FSL, Statistics and Machine Learning Toolbox, systems, fMRI, 2 references

Contribute

The authors of this paper can claim it, correct its record and validate its tracing map, and the maintainers of its code (its owner, or a public member of its organization) correct what it says of their repository; anyone signed in can ask for its removal. Every request goes to OSCR's own machine, which answers it; your account page follows them.

Sign in with ORCID to claim this paper as one of its authors, correct its record or validate its tracing map: when the paper's metadata lists your ORCID iD, you are recognized at once. Maintainers of its code: sign in with GitHub, then claim the repository on your account page.

Request its removal

To ask OSCR to remove this record, the copies of its authors' scripts or its tracing map, use the removal request page: signed in, you say who you are, what to remove and why, then review and confirm the request. Published rules decide every request (how).

Discussion, reproductions, activity

Discussion: questions and error reports about this paper and its code, from signed-in readers and its authors. It opens with sign-in.

Reproductions: reports from readers who ran the authors' code: what they reproduced, with which environment, commit and data. It opens with sign-in.

Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.