OSCR

Network localization of regional intrinsic neural activity alterations in migraine and their neurochemical correlates.

Code ↔ Paper

The paper beside its authors' code: matches between them have not been computed for this paper yet.

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,154 lines · 51 KB · no license

  1. % App designed with MATLAB App Designer
  2. classdef JuSpace < matlab.apps.AppBase
  3. % Components declaration
  4. properties (Access = public)
  5. UIFigure matlab.ui.Figure
  6. TabGroup matlab.ui.container.TabGroup
  7. Tab1 matlab.ui.container.Tab
  8. Tab2 matlab.ui.container.Tab
  9. Tab3 matlab.ui.container.Tab
  10. LogoImage matlab.ui.control.Image
  11. % Tab 1 components
  12. AtlasLabel matlab.ui.control.Label
  13. AtlasDropDown matlab.ui.control.DropDown
  14. SelectAtlasButton matlab.ui.control.Button
  15. AnalysisLabel matlab.ui.control.Label
  16. AnalysisDropDown matlab.ui.control.DropDown
  17. FirstSetButton matlab.ui.control.Button
  18. SecondSetButton matlab.ui.control.Button
  19. SelectSaveDirButton matlab.ui.control.Button
  20. SaveDirLabel matlab.ui.control.Label
  21. FirstSetListBox matlab.ui.control.ListBox
  22. SecondSetListBox matlab.ui.control.ListBox
  23. FirstSetLabel matlab.ui.control.Label
  24. SecondSetLabel matlab.ui.control.Label
  25. AnalysisTooltipLabel matlab.ui.control.Label
  26. NameSaveField matlab.ui.control.EditField
  27. NameSaveFieldLabel matlab.ui.control.Label
  28. % Tab 2 components
  29. NeuroTemplateLabel matlab.ui.control.Label
  30. NeuroTemplateListBox matlab.ui.control.ListBox
  31. CellularMarkerLabel matlab.ui.control.Label
  32. CellularMarkerListBox matlab.ui.control.ListBox
  33. MetricsLabel matlab.ui.control.Label
  34. MetricsListBox matlab.ui.control.ListBox
  35. RunAnalysisButton matlab.ui.control.Button
  36. PermutationsField matlab.ui.control.EditField
  37. PermutationsFieldLabel matlab.ui.control.Label
  38. T1CheckBox matlab.ui.control.CheckBox
  39. InstructionsLabel matlab.ui.control.Label
  40. % Tab 3 components
  41. PlotSelected matlab.ui.control.Button
  42. FigureNeuro matlab.ui.control.UIAxes
  43. ResultsTable matlab.ui.control.Table
  44. SwitchScatterLabel1 matlab.ui.control.Label
  45. SwitchScatterLabel2 matlab.ui.control.Label
  46. SwitchScatter matlab.ui.control.Switch
  47. SaveFigureButton matlab.ui.control.Button
  48. RankPlotCheckBox matlab.ui.control.CheckBox
  49. ResultsLabel matlab.ui.control.Label
  50. xaxisListLabel matlab.ui.control.Label
  51. xaxisList matlab.ui.control.ListBox
  52. yaxisList matlab.ui.control.ListBox
  53. FDRCheckBox matlab.ui.control.CheckBox
  54. % Navigation buttons
  55. NextTabButton matlab.ui.control.Button
  56. PrevTabButton matlab.ui.control.Button
  57. end
  58. properties (Access = private)
  59. list_PET;
  60. list_cell;
  61. files_set1;
  62. files_set2;
  63. atlas;
  64. Results;
  65. Tab3Enabled = false;
  66. dir_tool;
  67. end
  68. methods (Access = private)
  69. function tabChanged(app, event)
  70. selectedTab = event.NewValue;
  71. if selectedTab == app.Tab3 && ~app.Tab3Enabled
  72. % Block access: force back to Tab1
  73. uialert(app.UIFigure, 'Please set-up and run the analysis first.', 'Tab Locked');
  74. app.TabGroup.SelectedTab = app.Tab1; % revert selection
  75. end
  76. check_inputs(app)
  77. end
  78. % Navigate tabs
  79. function nextTab(app, ~) % <-- added 'event' here
  80. idx = find(app.TabGroup.Children == app.TabGroup.SelectedTab);
  81. if idx < 3
  82. app.TabGroup.SelectedTab = app.TabGroup.Children(idx + 1);
  83. end
  84. drawnow;
  85. check_inputs(app)
  86. end
  87. function prevTab(app, ~)
  88. idx = find(app.TabGroup.Children == app.TabGroup.SelectedTab);
  89. if idx > 1
  90. app.TabGroup.SelectedTab = app.TabGroup.Children(idx - 1);
  91. end
  92. check_inputs(app)
  93. end
  94. % Select custom Atlas
  95. function selectAtlas(app, ~, ~)
  96. [file, path] = uigetfile('*.nii;*.img', 'Select Atlas Image');
  97. atlas_all = app.atlas;
  98. atlas_all(end+1).name = file;
  99. atlas_all(end).folder = path;
  100. app.atlas = atlas_all;
  101. if isequal(file,0)
  102. app.AtlasDropDown.Value = 'm_labels_Neuromorphometrics.nii';
  103. else
  104. app.AtlasDropDown.Items = [app.AtlasDropDown.Items, {file}];
  105. app.AtlasDropDown.Value = file;
  106. end
  107. check_inputs(app)
  108. end
  109. % Study design options
  110. function updateAnalysisVisibility(app)
  111. % update visibility of set 2
  112. study_design_opt = find(ismember(app.AnalysisDropDown.Items,app.AnalysisDropDown.Value))-1;
  113. set2_opt = [1,2,5,6];
  114. if ismember(study_design_opt, set2_opt)
  115. app.SecondSetButton.Enable = 'on';
  116. else
  117. app.SecondSetButton.Enable = 'off';
  118. app.SecondSetListBox.Items = {''};
  119. app.files_set2 = {''};
  120. app.SecondSetButton.BackgroundColor = [0.5 0.7 0.9];
  121. end
  122. % Update tooltip based on dropdown selection
  123. switch study_design_opt
  124. % opt_comp = 1 --> es between
  125. % opt_comp = 2 --> es within
  126. % opt_comp = 3 --> mean list 1
  127. % opt_comp = 4 --> list 1 each
  128. % opt_comp = 5 --> ind z-score list 1 to list 2
  129. % opt_comp = 6 --> pair-wise difference list 1 to list 2
  130. % opt_comp = 7 --> ind z-scores from list 1
  131. % opt_comp = 8 --> list 1 each compares against null distribution of
  132. % correlation coefficients
  133. case 1
  134. app.AnalysisTooltipLabel.Text = sprintf('Computes and uses Cohen''s d effect size per region for set 1 versus set 2');
  135. case 2
  136. app.AnalysisTooltipLabel.Text = sprintf('Computes pre-post Cohen''s d effect size \nper region for set 1 relative to set 2. \nNumber of selected images must be the same for set 1 and 2');
  137. case 3
  138. app.AnalysisTooltipLabel.Text = sprintf('Uses mean per region from set 1');
  139. case 4
  140. app.AnalysisTooltipLabel.Text = sprintf('Tests each image from set 1 against a null distribution');
  141. case 5
  142. app.AnalysisTooltipLabel.Text = sprintf('Converts each image in set 1 to z-scores relative to images in set 2');
  143. case 6
  144. app.AnalysisTooltipLabel.Text = sprintf('Computes pair-wise differences for set 1 versus set 2 \nand tests these difference maps against null distribution. \nNumber of selected images must be the same for set 1 and 2');
  145. case 7
  146. app.AnalysisTooltipLabel.Text = sprintf('Converts each image in set 1 to z-scores relative to \nall other images in set 1');
  147. case 8
  148. app.AnalysisTooltipLabel.Text = sprintf('Tests the distribution of spatial correlation of all \nimages from set 1 against a null distribution');
  149. otherwise
  150. app.AnalysisTooltipLabel.Text = sprintf('Please select an analysis option');
  151. end
  152. check_inputs(app)
  153. end
  154. % Select First Image Set
  155. function selectFirstSet(app, ~, ~)
  156. app.files_set1 = cellstr(spm_select(Inf,'image','Select files for set 1'));
  157. for i = 1:length(app.files_set1)
  158. [~,file] = fileparts(app.files_set1{i});
  159. set1{i} = file;
  160. end
  161. app.UIFigure.Visible = 'off';
  162. app.UIFigure.Visible = 'on'; % keeps figure in the foreground
  163. if isequal(set1,0)
  164. app.FirstSetListBox.Items = {''};
  165. else
  166. if ischar(set1)
  167. set1 = {set1};
  168. end
  169. app.FirstSetListBox.Items = set1;
  170. app.FirstSetListBox.Visible = 'on';
  171. app.FirstSetLabel.Visible = 'on';
  172. app.FirstSetButton.BackgroundColor = [0.4 0.8 0.6];
  173. end
  174. check_inputs(app)
  175. end
  176. % Select Second Image Set (optional)
  177. function selectSecondSet(app, ~, ~)
  178. ana_opt = find(ismember(app.AnalysisDropDown.Items,app.AnalysisDropDown.Value))-1;
  179. app.files_set2 = cellstr(spm_select(Inf,'image','Select files for set 1'));
  180. if ismember(ana_opt,[2 6]) && length(app.files_set1) ~= length(app.files_set2)
  181. uialert(app.UIFigure, 'For analysis options 2 and 6 the number of images in set 2 must match the number selected in set 1', 'Check selection');
  182. else
  183. for i = 1:length(app.files_set2)
  184. [~,file] = fileparts(app.files_set2{i});
  185. set2{i} = file;
  186. end
  187. app.UIFigure.Visible = 'off';
  188. app.UIFigure.Visible = 'on';
  189. if isequal(set2,0)
  190. app.SecondSetListBox.Visible = 'off';
  191. app.SecondSetLabel.Visible = 'off';
  192. else
  193. if ischar(set2)
  194. set2 = {set2};
  195. end
  196. app.SecondSetListBox.Items = set2;
  197. app.SecondSetListBox.Visible = 'on';
  198. app.SecondSetLabel.Visible = 'on';
  199. app.SecondSetButton.BackgroundColor = [0.4 0.8 0.6];
  200. end
  201. check_inputs(app)
  202. end
  203. end
  204. % Select save directory
  205. function selectSaveDir(app, ~, ~)
  206. saveDir = uigetdir;
  207. if saveDir ~= 0
  208. app.SaveDirLabel.Text = saveDir;
  209. app.SelectSaveDirButton.BackgroundColor = [0.4 0.8 0.6];
  210. end
  211. app.UIFigure.Visible = 'off';
  212. app.UIFigure.Visible = 'on';
  213. drawnow;
  214. check_inputs(app);
  215. end
  216. function run_analysis(app,~)
  217. d = uiprogressdlg(app.UIFigure, 'Title', 'Please Wait', 'Message', 'Running analysis...', 'Indeterminate', 'on', 'Cancelable', 'off');
  218. try
  219. % get selections from tab 1 (Inputs)
  220. try
  221. d.Message = 'Loading all settings ...';
  222. atlases = app.atlas;
  223. atlas_sel = app.AtlasDropDown.Value;
  224. atlas_all = app.AtlasDropDown.Items;
  225. [~,ind_atlas] = ismember(atlas_sel, atlas_all);
  226. atlas = fullfile(atlases(ind_atlas).folder,atlases(ind_atlas).name);
  227. ana_opt = find(ismember(app.AnalysisDropDown.Items,app.AnalysisDropDown.Value))-1;
  228. list1 = app.files_set1;
  229. list2 = app.files_set2;
  230. dir_save = app.SaveDirLabel.Text;
  231. name_save = app.NameSaveField.Value;
  232. app.SwitchScatter.Value = {'Bar plot'};
  233. app.xaxisList.Items = {''};
  234. app.yaxisList.Items = {''};
  235. % get selections from tab 2 (Templates and Metrics)
  236. [ind_PET,ind_cell,ind_ana] = SelectTemplates(app);
  237. files_PET = app.list_PET(ind_PET);
  238. files_cell = app.list_cell(ind_cell);
  239. files_PET = [files_PET;files_cell];
  240. opt_perm = 0;
  241. opt_spat_perm = 0;
  242. Nperm = str2num(app.PermutationsField.Value);
  243. switch ana_opt
  244. case {1,2,5,6}
  245. opt_perm = 1;
  246. case {3,4,7,8}
  247. opt_spat_perm = 1;
  248. end
  249. image_save = fullfile(dir_save, [name_save '.nii']);
  250. opt_T1 = app.T1CheckBox.Value;
  251. options = [ana_opt ind_ana opt_perm opt_T1 opt_spat_perm];
  252. catch ME
  253. uialert(app.UIFigure, getReport(ME), 'Analysis Error');
  254. fid = fopen('error_log.txt', 'a');
  255. fprintf(fid, '[%s] ERROR: %s\n', char(datetime), ME.message);
  256. fprintf(fid, '%s\n\n', getReport(ME, 'extended'));
  257. fclose(fid);
  258. end
  259. d.Message = 'Computing spatial correlations...';
  260. try
  261. Results = compute_DomainGauges(list1,list2,files_PET,atlas, options,image_save);
  262. catch ME
  263. fid = fopen('error_log.txt', 'a');
  264. fprintf(fid, '[%s] ERROR: %s\n', char(datetime), ME.message);
  265. fprintf(fid, '%s\n\n', getReport(ME, 'extended'));
  266. fclose(fid);
  267. end
  268. opt_for_perm = [1,2,5,6];
  269. opt_for_spat_perm = [3, 4, 7, 8];
  270. try
  271. if options(3)==1 && ismember(options(1),opt_for_perm)% && options(2)~=3
  272. d.Message = 'Computing exact p-value...';
  273. disp('Computing exact p-value');
  274. [p_exact,~] = compute_exact_pvalue(Results.data_set1,Results.data_set2,Results.data_PET,Results.res,Nperm,options,Results.T1,Results.stats);
  275. Results.Resh(:,end+1) = [{'p_exact'}; num2cell_my(p_exact')];
  276. end
  277. if options(5)==1 && ismember(options(1),opt_for_spat_perm)
  278. d.Message = 'Computing exact spatial p-value. This option may take quite a while if the null maps are not yet precomputed';
  279. disp('Computing exact spatial p-value')
  280. [p_exact,~,~] = compute_exact_spatial_pvalue(Results.data_set1,Results.data_PET,atlas,Results.res,Nperm,options,files_PET, Results.T1,Results.stats,d);
  281. Results.Resh(:,end+1) = [{'p_exact_spatial'}; num2cell_my(p_exact')];
  282. end
  283. [h_sig, crit_p, adj_p_fdrBH] = fdr_bh(p_exact, 0.05);
  284. Results.Resh(:,end+1) = [{'p_fdr_BH'}; num2cell_my(adj_p_fdrBH)];
  285. catch ME
  286. fid = fopen('error_log.txt', 'a');
  287. fprintf(fid, '[%s] ERROR: %s\n', char(datetime), ME.message);
  288. fprintf(fid, '%s\n\n', getReport(ME, 'extended'));
  289. fclose(fid);
  290. end
  291. d.Message = 'Saving and visualizing results...';
  292. if options(2)<3
  293. Results.Resh = Results.Resh(:,[1 6 7 2 3 4 5]);
  294. else
  295. Results.Resh = Results.Resh(:,[1 5 6 2 3 4]);
  296. end
  297. Results.p_exact = p_exact;
  298. Results.p_exact_fdr_BH = adj_p_fdrBH;
  299. Results.dir_save = dir_save;
  300. Results.Nperm = Nperm;
  301. Results.options = options;
  302. Results.atlas = atlas;
  303. Results.filesPET = files_PET;
  304. Results.set1_images = list1;
  305. Results.set2_images = list2;
  306. app.Results = Results;
  307. app.ResultsTable.ColumnName = Results.Resh(1,:);
  308. data = Results.Resh(2:end,:);
  309. app.ResultsTable.Data = data;
  310. save_results(Results,app,name_save);
  311. try
  312. bar_plot(app,h_sig);
  313. app.TabGroup.SelectedTab = app.TabGroup.Children(3);
  314. app.Tab3Enabled = true;
  315. catch ME
  316. fid = fopen('error_log.txt', 'a');
  317. fprintf(fid, '[%s] ERROR: %s\n', char(datetime), ME.message);
  318. fprintf(fid, '%s\n\n', getReport(ME, 'extended'));
  319. fclose(fid);
  320. end
  321. catch ME2
  322. uialert(app.UIFigure, getReport(ME2), 'Analysis Error');
  323. end
  324. close(d);
  325. end
  326. function listBoxItemClicked(app, event)
  327. check_inputs(app);
  328. end
  329. function switchscatterbox(app)
  330. switch_plot = app.SwitchScatter.Value;
  331. if strcmp(switch_plot,'Scatter plot')
  332. cla(app.FigureNeuro, 'reset');
  333. app.xaxisList.Enable = 'on';
  334. app.yaxisList.Enable = 'on';
  335. app.RankPlotCheckBox.Enable = 'on';
  336. app.FDRCheckBox.Enable = 'off';
  337. app.PlotSelected.Enable = 'on';
  338. all = app.Results.filesPET;
  339. for i = 1:length(all)
  340. [~,name] = fileparts(all{i});
  341. xlist_all{i,1} = name;
  342. end
  343. app.xaxisList.Items = xlist_all;
  344. if size(app.Results.data,1) > 1
  345. app.yaxisList.Items = app.files_set1;
  346. else
  347. app.yaxisList.Items = {'data modality'};
  348. end
  349. else
  350. app.FDRCheckBox.Enable = 'on';
  351. app.FDRCheckBox.Value = false;
  352. cla(app.FigureNeuro, 'reset');
  353. app.xaxisList.Enable = 'off';
  354. app.yaxisList.Enable = 'off';
  355. app.RankPlotCheckBox.Enable = 'off';
  356. app.PlotSelected.Enable = 'off';
  357. bar_plot(app);
  358. end
  359. end
  360. function addSignficanttoBoxPlot(app)
  361. plot_sig = app.FDRCheckBox.Value;
  362. if plot_sig
  363. try
  364. h_sig = app.Results.p_exact_fdr_BH<0.05;
  365. bar_plot(app,h_sig);
  366. catch
  367. uialert(app.UIFigure, 'FDR significance not computed','Information');
  368. end
  369. else
  370. bar_plot(app);
  371. end
  372. end
  373. function plotSelected(app)
  374. scatter_plot(app);
  375. end
  376. function exportWithPrint(app)
  377. % Create a new figure and axes
  378. plot_opt = app.SwitchScatter.Value;
  379. if strcmp(plot_opt,'Scatter plot')
  380. f = figure('Position',[400 400 800 600],'Visible', 'off');
  381. else
  382. if length(app.Results.filesPET)<3
  383. f = figure('Position',[400 400 500 500],'Visible', 'off');
  384. elseif length(app.Results.filesPET)<10
  385. f = figure('Position',[400 200 length(app.Results.filesPET).*150 700],'Visible', 'off');
  386. else
  387. f = figure('Position',[400 200 length(app.Results.filesPET).*100 700],'Visible', 'off');
  388. end
  389. end
  390. ax = axes(f);
  391. % Copy content from App Designer UIAxes
  392. copyobj(allchild(app.FigureNeuro), ax);
  393. % Copy axis labels and limits
  394. ax.XLim = app.FigureNeuro.XLim;
  395. ax.YLim = app.FigureNeuro.YLim;
  396. xlabel(ax, app.FigureNeuro.XLabel.String);
  397. ylabel(ax, app.FigureNeuro.YLabel.String);
  398. title(ax, app.FigureNeuro.Title.String);
  399. set(ax, 'XTick', app.FigureNeuro.XTick);
  400. set(ax, 'XTickLabel', app.FigureNeuro.XTickLabel);
  401. set(ax, 'FontSize', app.FigureNeuro.FontSize);
  402. set(ax, 'XTickLabelRotation', app.FigureNeuro.XTickLabelRotation);
  403. if strcmp(plot_opt,'Scatter plot')
  404. grid on
  405. end
  406. try
  407. legend(ax, app.FigureNeuro.Legend.String, 'Location', 'northeastoutside');
  408. catch
  409. end
  410. grid on
  411. set(gcf,'color','w');
  412. time_now = datestr(datetime('now'),'ddmmmyyyy_HHMMSS');
  413. if strcmp(plot_opt,'Scatter plot')
  414. print(f,fullfile(app.Results.dir_save,['Scatter_' app.NameSaveField.Value '_' time_now '.png']),'-dpng','-r300');
  415. f.Visible='on';
  416. savefig(f,fullfile(app.Results.dir_save,['Scatter_' app.NameSaveField.Value '_' time_now '.fig']));
  417. f.Visible='off';
  418. else
  419. print(f,fullfile(app.Results.dir_save,['Bar_' app.NameSaveField.Value '_' time_now '.png']),'-dpng','-r300');
  420. f.Visible='on';
  421. saveas(f,fullfile(app.Results.dir_save,['Bar_' app.NameSaveField.Value '_' time_now '.fig']),'fig');
  422. f.Visible='off';
  423. end
  424. close(f);
  425. end
  426. function loadAnalysis(app)
  427. d = uiprogressdlg(app.UIFigure, 'Title', 'Please Wait', 'Message', 'Loading analysis...', 'Indeterminate', 'on', 'Cancelable', 'off');
  428. [file, path] = uigetfile('*.mat', 'Load Analysis');
  429. if isequal(file, 0)
  430. return;
  431. end
  432. loaded = load(fullfile(path, file));
  433. if ~isfield(loaded, 'app_save')
  434. uialert(app.UIFigure, 'Invalid file format.', 'Error');
  435. return;
  436. end
  437. analysisData = loaded.app_save;
  438. % Restore Tab 1
  439. app.AtlasDropDown.Items = analysisData.AtlasDropDown.Items;
  440. app.AtlasDropDown.Value = analysisData.AtlasDropDown.Value;
  441. app.AnalysisDropDown.Items = analysisData.AnalysisDropDown.Items;
  442. app.AnalysisDropDown.Value = analysisData.AnalysisDropDown.Value;
  443. app.FirstSetListBox.Items = analysisData.FirstSetListBox.Items;
  444. app.FirstSetListBox.Value = analysisData.FirstSetListBox.Value;
  445. app.SecondSetListBox.Items = analysisData.SecondSetListBox.Items;
  446. app.SecondSetListBox.Value = analysisData.SecondSetListBox.Value;
  447. app.AnalysisTooltipLabel.Text = analysisData.AnalysisTooltipLabel.Text;
  448. app.NameSaveField.Value = analysisData.NameSaveField.Value;
  449. app.SaveDirLabel.Text = analysisData.SaveDirLabel.Text;
  450. app.files_set1 = analysisData.files_set1;
  451. app.files_set2 = analysisData.files_set2;
  452. app.list_PET = analysisData.list_PET;
  453. app.list_cell = analysisData.list_cell;
  454. app.atlas = analysisData.atlas;
  455. % Restore Tab 2
  456. app.NeuroTemplateListBox.Items = analysisData.NeuroTemplateListBox.Items;
  457. app.NeuroTemplateListBox.Value = analysisData.NeuroTemplateListBox.Value;
  458. app.CellularMarkerListBox.Items = analysisData.CellularMarkerListBox.Items;
  459. app.CellularMarkerListBox.Value = analysisData.CellularMarkerListBox.Value;
  460. app.MetricsListBox.Items = analysisData.MetricsListBox.Items;
  461. app.MetricsListBox.Value = analysisData.MetricsListBox.Value;
  462. app.PermutationsField.Value = analysisData.PermutationsField.Value;
  463. app.T1CheckBox.Value = analysisData.T1CheckBox.Value;
  464. % Restore Tab 3
  465. if ~isempty(analysisData.ResultsTable.Data)
  466. cla(app.FigureNeuro, 'reset');
  467. app.TabGroup.SelectedTab = app.TabGroup.Children(3);
  468. app.Tab3Enabled = true;
  469. app.ResultsTable.ColumnName = analysisData.ResultsTable.ColumnName;
  470. app.ResultsTable.Data = analysisData.ResultsTable.Data;
  471. app.SwitchScatter.Value = analysisData.SwitchScatter.Value;
  472. app.RankPlotCheckBox.Value = analysisData.RankPlotCheckBox.Value;
  473. app.xaxisList.Items = analysisData.xaxisList.Items;
  474. app.xaxisList.Value = analysisData.xaxisList.Value;
  475. app.yaxisList.Items = analysisData.yaxisList.Items;
  476. app.yaxisList.Value = analysisData.yaxisList.Value;
  477. app.Results = loaded.Results;
  478. app.xaxisList.Enable = 'off';
  479. app.yaxisList.Enable = 'off';
  480. app.RankPlotCheckBox.Enable = 'off';
  481. app.PlotSelected.Enable = 'off';
  482. app.TabGroup.SelectedTab = app.TabGroup.Children(3);
  483. bar_plot(app);
  484. else
  485. app.TabGroup.SelectedTab = app.TabGroup.Children(1);
  486. app.Tab3Enabled = false;
  487. end
  488. close(d);
  489. drawnow;
  490. check_inputs(app);
  491. uialert(app.UIFigure, 'Analysis loaded.', 'Loaded');
  492. end
  493. function saveAnalysis(app)
  494. Results = app.Results;
  495. % Results.JuSpace_version = 'v2.1';
  496. % file_save = fullfile(path,file);
  497. % save(file_save,'Results','app_save');
  498. save_results(Results,app);
  499. uialert(app.UIFigure, 'Analysis saved.', 'Success');
  500. end
  501. end
  502. methods (Access = private)
  503. function createComponents(app)
  504. warning off
  505. if isdeployed
  506. [~, ~] = system('path');
  507. app.dir_tool = pwd;
  508. else
  509. app.dir_tool= fileparts(which('JuSpace'));
  510. end
  511. % Main UI figure
  512. app.UIFigure = uifigure('Name', 'JuSpace 2.1', 'Position', [100, 100, 900, 600], 'Color', [0.96 0.96 0.98], 'AutoResizeChildren','on');
  513. fileMenu = uimenu(app.UIFigure, 'Text', 'File');
  514. uimenu(fileMenu, 'Text', 'Load Existing Analysis...','MenuSelectedFcn', @(src, event) loadAnalysis(app));
  515. uimenu(fileMenu, 'Text', 'Save Analysis Settings...', 'MenuSelectedFcn', @(src, event) saveAnalysis(app));
  516. app.LogoImage = uiimage(app.UIFigure, 'ImageSource', fullfile(app.dir_tool,'splash.png'),'Position', [420, 1, 60, 60]);
  517. % Tab Group
  518. app.TabGroup = uitabgroup(app.UIFigure, 'Position', [10 60 880 520],'SelectionChangedFcn', @(src,event) tabChanged(app, event));
  519. % Tab 1
  520. app.Tab1 = uitab(app.TabGroup, 'Title', 'Inputs');
  521. % Update AtlasDropDown items, keeping existing entries
  522. % Atlas options
  523. app.AtlasLabel = uilabel(app.Tab1, 'Text', 'Select Atlas:', 'Position', [20, 440, 100, 22], 'FontWeight', 'bold');
  524. app.AtlasDropDown = uidropdown(app.Tab1, 'Items', {'Atlas1'}, 'Position', [130, 440, 250, 22]);
  525. app.SelectAtlasButton = uibutton(app.Tab1, 'push', 'Text', 'Custom Atlas', 'Position', [400, 440, 120, 22], 'BackgroundColor',[0.5 0.7 0.9],'FontColor','white','ButtonPushedFcn', @app.selectAtlas);
  526. %Study design options
  527. study_designs = {'Select an option', '1) Effect size between groups', '2) Effect size within group','3) Mean from set 1', '4) Set 1 each image', '5) Individual z-scores for set 1 relative to set 2', '6) pair-wise difference set 1 relative to set 2','7) Leave-one-out from set 1', '8) Set 1 each compares against null distribution'};
  528. app.AnalysisTooltipLabel = uilabel(app.Tab1, 'Text', 'Description of the selected spatial correlation approach', 'Position', [400, 390, 400, 44],'FontAngle', 'italic', 'FontColor', [0.3 0.3 0.3]);
  529. app.AnalysisLabel = uilabel(app.Tab1, 'Text', 'Study Design:', 'Position', [20, 400, 100, 22], 'FontWeight', 'bold');
  530. app.AnalysisDropDown = uidropdown(app.Tab1, 'Items', study_designs, 'Position', [130, 400, 250, 22],'ValueChangedFcn', @(src, event) updateAnalysisVisibility(app));
  531. app.SelectSaveDirButton = uibutton(app.Tab1, 'push', 'Text', 'Select Save Directory', 'Position', [20, 350 360, 22],'BackgroundColor',[0.8 0.8 0.5],'FontColor','white' ,'ButtonPushedFcn', @app.selectSaveDir);
  532. app.SaveDirLabel = uilabel(app.Tab1, 'Text', '', 'Position', [20, 320, 600, 22]);
  533. % Label for editable field
  534. app.NameSaveFieldLabel = uilabel(app.Tab1, 'Text', 'Name save', 'Position', [400, 370, 100, 22], 'FontWeight', 'bold');
  535. app.NameSaveField = uieditfield(app.Tab1, 'text', 'Position', [400, 350 200, 22], 'Value', ''); % initial value
  536. app.FirstSetButton = uibutton(app.Tab1, 'push', 'Text', 'Select First Set', 'Position', [20, 290, 120, 22],'BackgroundColor',[0.5 0.7 0.9],'FontColor','white','ButtonPushedFcn', @app.selectFirstSet);
  537. app.FirstSetLabel = uilabel(app.Tab1, 'Text', 'First Set Images:', 'Position', [20, 260, 340, 20],'FontWeight', 'bold');
  538. app.FirstSetListBox = uilistbox(app.Tab1,'Items',{''}, 'Position', [20, 30, 380, 220]);
  539. app.SecondSetButton = uibutton(app.Tab1, 'push', 'Text', 'Select Second Set', 'Position', [450, 290, 120, 22],'BackgroundColor',[0.5 0.7 0.9],'FontColor','white', 'ButtonPushedFcn', @app.selectSecondSet);
  540. app.SecondSetLabel = uilabel(app.Tab1, 'Text', 'Second Set Images:', 'Position', [450, 260, 340, 20],'FontWeight', 'bold');
  541. app.SecondSetListBox = uilistbox(app.Tab1,'Items',{''}, 'Position', [450, 30, 380, 220]);
  542. app.SecondSetButton.Enable = 'off';
  543. % Components in Tab 2
  544. % Tab 2
  545. app.Tab2 = uitab(app.TabGroup, 'Title', 'Templates & Metrics');
  546. dir_PET = fullfile(app.dir_tool,'PETatlas');
  547. files_PET = select_con_maps_forfMRI_my(dir_PET,'PETatlas','.*.nii');
  548. for i = 1:length(files_PET)
  549. [~,file] = fileparts(files_PET{i});
  550. list_PET{i} = file;
  551. end
  552. app.list_PET = files_PET;
  553. app.NeuroTemplateLabel = uilabel(app.Tab2,'Text','PET/Neurotransmitter Templates:','Position',[20,470,200,22],'FontWeight','bold');
  554. app.NeuroTemplateListBox = uilistbox(app.Tab2,'Items',list_PET,'Position',[20,110,260,360],'Multiselect','on','ValueChangedFcn', @(src,event) listBoxItemClicked(app, event));
  555. app.NeuroTemplateListBox.Value = cell(0,0);
  556. dir_cell = fullfile(app.dir_tool,'CELLatlas');
  557. files_cell = select_con_maps_forfMRI_my(dir_cell,'CELLatlas','.*.nii');
  558. for i = 1:length(files_cell)
  559. [path,file] = fileparts(files_cell{i});
  560. list_cell{i} = file;
  561. end
  562. app.list_cell = files_cell;
  563. app.CellularMarkerLabel = uilabel(app.Tab2,'Text','Cellular Markers:','Position',[310,470,300,22],'FontWeight','bold');
  564. app.CellularMarkerListBox = uilistbox(app.Tab2,'Items',list_cell,'Position',[310,110,260,360],'Multiselect','on','ValueChangedFcn', @(src,event) listBoxItemClicked(app, event));
  565. app.CellularMarkerListBox.Value = cell(0,0);
  566. app.MetricsLabel = uilabel(app.Tab2,'Text','Select Analysis Type:','Position',[600,470,200,22],'FontWeight','bold');
  567. app.MetricsListBox = uilistbox(app.Tab2,'Items',{'Spearman','Pearson','Multiple Linear Regression'},'Position',[600,110,260,360],'Multiselect','off','ValueChangedFcn', @(src,event) listBoxItemClicked(app, event));
  568. app.MetricsListBox.Value = cell(0,0);
  569. app.PermutationsFieldLabel = uilabel(app.Tab2, 'Text', 'Number of permutations', 'Position', [20, 90, 200, 22], 'FontWeight', 'bold');
  570. app.PermutationsField = uieditfield(app.Tab2, 'text', 'Position', [20, 70, 150, 22], 'Value', '1000'); % initial value
  571. app.T1CheckBox = uicheckbox(app.Tab2, 'Text', 'Partial volume effect correction using T1 probabilities', 'Position', [200, 60, 350, 30]);
  572. app.RunAnalysisButton = uibutton(app.Tab2,'push','Text','Run Analysis','Position',[20,20,840,40],'BackgroundColor',[0.2 0.6 0.8],'FontColor','white', 'ButtonPushedFcn', @(src, event) run_analysis(app));
  573. app.RunAnalysisButton.Enable = 'off';
  574. app.InstructionsLabel = uilabel(app.Tab2, 'Text', sprintf('Please cite the reference for each image as described in \nsources_template_release.txt. \nTo (un)select multiple images keep CTRL key pressed'), 'Position', [550, 60, 330, 50]);
  575. % Tab 3
  576. app.Tab3 = uitab(app.TabGroup, 'Title', 'Results');
  577. app.FigureNeuro = uiaxes(app.Tab3,'Position', [50, 60, 430, 430]);
  578. title(app.FigureNeuro, 'Results');
  579. app.ResultsLabel = uilabel(app.Tab3, 'Text', 'Results table', 'Position', [650, 470, 100, 22],'FontWeight','bold');
  580. app.ResultsTable = uitable(app.Tab3,'Position', [650, 20, 200, 450], 'Data', {},'ColumnName', {'Column 1', 'Column 2'},'RowName', {});
  581. % plot options
  582. app.SwitchScatter = uiswitch(app.Tab3, 'slider','Position', [60, 10, 45, 20],'Items', {'Bar plot', 'Scatter plot'}, 'ValueChangedFcn', @(src,event) switchscatterbox(app));
  583. app.RankPlotCheckBox = uicheckbox(app.Tab3, 'Text', 'Rank Plot', 'Position', [200, 8, 90, 20]);
  584. app.FDRCheckBox = uicheckbox(app.Tab3, 'Text', 'FDR sign.', 'Position', [290, 8, 100, 20],'ValueChangedFcn', @(src,event) addSignficanttoBoxPlot(app));
  585. app.SaveFigureButton = uibutton(app.Tab3,'push','Text','Save figure','Position',[400,10,90,20], 'BackgroundColor',[0.2 0.6 0.8],'FontColor','white', 'ButtonPushedFcn', @(src, event) exportWithPrint(app));
  586. app.xaxisListLabel = uilabel(app.Tab3, 'Text', 'Select plot items', 'Position', [530, 470, 100, 22],'FontWeight','bold');
  587. app.xaxisList = uilistbox(app.Tab3,'Items',{'x axis'},'Position',[530,260,110,210],'Multiselect','on');
  588. app.yaxisList = uilistbox(app.Tab3,'Items',{'y axis'},'Position',[530,40,110,210],'Multiselect','on');
  589. app.PlotSelected = uibutton(app.Tab3,'push','Text','Plot selected','Position',[530,20,110,20], 'ButtonPushedFcn', @(src, event) plotSelected(app));
  590. app.xaxisList.Enable = 'off';
  591. app.RankPlotCheckBox.Enable = 'off';
  592. app.PlotSelected.Enable = 'off';
  593. app.yaxisList.Enable = 'off';
  594. % Navigation Buttons
  595. app.PrevTabButton = uibutton(app.UIFigure, 'push', 'Text', 'Previous', 'Position', [10, 20, 100, 30], 'ButtonPushedFcn', @(src,event) app.prevTab(event));
  596. app.NextTabButton = uibutton(app.UIFigure, 'push', 'Text', 'Next', 'Position', [790, 20, 100, 30], 'ButtonPushedFcn', @(src,event) app.nextTab(event));
  597. end
  598. end
  599. methods (Access = public)
  600. function app = JuSpace
  601. createComponents(app);
  602. load_atlases(app);
  603. end
  604. end
  605. end
  606. function load_atlases(app) % checks for available atlases and sets the default
  607. dir_juspace = app.dir_tool;
  608. % dir_juspace = fileparts(which('JuSpace'));
  609. dir_atlas = dir(fullfile(dir_juspace, 'atlas','*.nii')); % Adjust file extension if needed
  610. app.atlas = dir_atlas;
  611. atlases = {dir_atlas.name};
  612. app.AtlasDropDown.Items = atlases;
  613. app.AtlasDropDown.Value = 'm_labels_Neuromorphometrics.nii';
  614. end
  615. function [check_analysis] = check_inputs(app)
  616. %check inputs
  617. % tab 1
  618. study_design = find(ismember(app.AnalysisDropDown.Items,app.AnalysisDropDown.Value))-1;
  619. study_design_opt = study_design>0;
  620. set2_opt = [1,2,5,6];
  621. list1_opt = sum(~isemptycell(app.FirstSetListBox.Items))>0;
  622. save_dir_opt = isdir(app.SaveDirLabel.Text);
  623. check_all = [study_design_opt list1_opt save_dir_opt];
  624. if ismember(study_design, set2_opt)
  625. list2_opt = sum(~isemptycell(app.SecondSetListBox.Items))>0;
  626. check_all = [check_all list2_opt];
  627. end
  628. [ind1,ind2,ind_ana] = SelectTemplates(app);
  629. ind_check = ~isempty([ind1 ind2]);
  630. ind_ana_check = ~isempty(ind_ana);
  631. check_all = [check_all ind_check ind_ana_check];
  632. if true(check_all)
  633. app.RunAnalysisButton.Enable = 'on';
  634. drawnow;
  635. else
  636. app.RunAnalysisButton.Enable = 'off';
  637. drawnow;
  638. end
  639. end
  640. function [ind_PET,ind_cell,ind_ana] = SelectTemplates(app)
  641. selectedItems = app.NeuroTemplateListBox.Value;
  642. allItems = app.NeuroTemplateListBox.Items;
  643. [~, ind_PET] = ismember(selectedItems, allItems);
  644. selectedItemsCell = app.CellularMarkerListBox.Value;
  645. allItemsCell = app.CellularMarkerListBox.Items;
  646. [~, ind_cell] = ismember(selectedItemsCell, allItemsCell);
  647. selectedItems = app.MetricsListBox.Value;
  648. allItems = app.MetricsListBox.Items;
  649. [~, ind_ana] = ismember(selectedItems, allItems);
  650. end
  651. function save_results(Results,app,name_save)
  652. Results.JuSpace_version = 'v2.1';
  653. % Save Tab 1
  654. app_save.AtlasDropDown.Items = app.AtlasDropDown.Items;
  655. app_save.AtlasDropDown.Value = app.AtlasDropDown.Value;
  656. app_save.AnalysisDropDown.Items = app.AnalysisDropDown.Items;
  657. app_save.AnalysisDropDown.Value = app.AnalysisDropDown.Value;
  658. app_save.FirstSetListBox.Items = app.FirstSetListBox.Items;
  659. app_save.FirstSetListBox.Value = app.FirstSetListBox.Value;
  660. app_save.SecondSetListBox.Items = app.SecondSetListBox.Items;
  661. app_save.SecondSetListBox.Value = app.SecondSetListBox.Value;
  662. app_save.AnalysisTooltipLabel.Text = app.AnalysisTooltipLabel.Text;
  663. app_save.NameSaveField.Value = app.NameSaveField.Value;
  664. app_save.SaveDirLabel.Text = app.SaveDirLabel.Text;
  665. app_save.files_set1 = app.files_set1;
  666. app_save.files_set2 = app.files_set2;
  667. app_save.list_PET = app.list_PET;
  668. app_save.list_cell = app.list_cell;
  669. app_save.atlas = app.atlas;
  670. % Save Tab 2
  671. try
  672. app_save.NeuroTemplateListBox.Items = app.NeuroTemplateListBox.Items;
  673. app_save.NeuroTemplateListBox.Value = app.NeuroTemplateListBox.Value;
  674. app_save.CellularMarkerListBox.Items = app.CellularMarkerListBox.Items;
  675. app_save.CellularMarkerListBox.Value = app.CellularMarkerListBox.Value;
  676. app_save.MetricsListBox.Items = app.MetricsListBox.Items;
  677. app_save.MetricsListBox.Value = app.MetricsListBox.Value;
  678. app_save.PermutationsField.Value = app.PermutationsField.Value;
  679. app_save.T1CheckBox.Value = app.T1CheckBox.Value;
  680. catch
  681. end
  682. time_now = datestr(datetime('now'),'ddmmmyyyy_HHMMSS');
  683. % Save Tab 3
  684. try
  685. app_save.TabGroup.SelectedTab = app.TabGroup.Children(3);
  686. app_save.Tab3Enabled = true;
  687. app_save.ResultsTable.ColumnName = app.Results.Resh(1,:);
  688. app_save.ResultsTable.Data = app.ResultsTable.Data;
  689. app_save.SwitchScatter.Value = app.SwitchScatter.Value;
  690. app_save.RankPlotCheckBox.Value = app.RankPlotCheckBox.Value;
  691. app_save.xaxisList.Items = app.xaxisList.Items;
  692. app_save.xaxisList.Value = app.xaxisList.Value;
  693. app_save.yaxisList.Items = app.yaxisList.Items;
  694. app_save.yaxisList.Value = app.yaxisList.Value;
  695. app_save.Results = app.Results;
  696. app_save.xaxisList.Enable = 'off';
  697. app_save.yaxisList.Enable = 'off';
  698. app_save.RankPlotCheckBox.Enable = 'off';
  699. app_save.PlotSelected.Enable = 'off';
  700. writecell(app.Results.Resh,fullfile(Results.dir_save,['ResultsTable_' name_save '_' time_now '.csv']),'Delimiter',';');
  701. catch
  702. end
  703. if ~exist('name_save','var')
  704. [file, path] = uiputfile('*.mat', 'Save Analysis to...');
  705. if isequal(file, 0)
  706. return; % User canceled
  707. end
  708. save(fullfile(path,file),'Results','app_save');
  709. else
  710. name_save = add_suffix(name_save,Results.options);
  711. file_save = fullfile(Results.dir_save,[name_save '.mat']);
  712. save(file_save,'Results','app_save');
  713. end
  714. end
  715. function bar_plot(app,h_sig)
  716. cla(app.FigureNeuro, 'reset');
  717. Results = app.Results;
  718. name_save = app.NameSaveField.Value;
  719. res = Results.stats.res_ind;
  720. ind_plot =[];
  721. for i = 1:size(res,1)
  722. for j = 1:size(res,2)
  723. ind_plot(end+1,1) = j;
  724. end
  725. end
  726. vals_plot= res; %cell2num_my(Resh(2:end,3));
  727. for i = 1:length(Results.filesPET)
  728. all_i = vals_plot(:,i);%vals_plot(ind_plot==i);
  729. size_y_xi = sum(ind_plot==i);
  730. y_dist = abs(vals_plot(ind_plot==i) - mean(vals_plot(ind_plot==i)));
  731. y_dist_inv = abs(y_dist -max(y_dist))./max(abs(y_dist -max(y_dist)));
  732. if isnan(y_dist_inv)
  733. y_dist_inv = rand(size(y_dist_inv));
  734. end
  735. x_n_n(ind_plot==i) = ind_plot(ind_plot==i) + 0.7.*(rand(size_y_xi,1)-0.5).*y_dist_inv;
  736. all_ii = all_i(~isinf(all_i));
  737. m_x(i) = mean(all_ii);
  738. std_x(i,1) = 1.95996.*std(all_ii)./sqrt(length(all_ii));
  739. end
  740. % plot specs
  741. n_files = length(Results.set1_images);
  742. marker_color = [0 0.7 1];
  743. opt_plot = 1;
  744. if opt_plot == 1
  745. bar_color = generate_colors_nice_my(length(Results.filesPET));
  746. else
  747. bar_color = generate_colors_blue_my(length(Results.filesPET));
  748. end
  749. opt_comp = Results.options(1);
  750. if opt_comp<3 || size(Results.data,1)==1
  751. h2 = bar(app.FigureNeuro,1:length(Results.filesPET),diag(m_x),0.9,'stacked','EdgeColor','none');
  752. if min(m_x)>0
  753. min_m_x = 0;
  754. else
  755. min_m_x = min(m_x);
  756. end
  757. if max(m_x)<0
  758. max_m_x = 0;
  759. else
  760. max_m_x = max(m_x);
  761. end
  762. ylim(app.FigureNeuro,[min_m_x.*1.1 max_m_x.*1.1]);
  763. else
  764. h2 = boxplot(app.FigureNeuro, vals_plot,'widths',0.9,'outliersize',2);
  765. set(app.FigureNeuro,'Visible','on');
  766. % set(gca,'XTickLabel',Rec_list);
  767. h3 = findobj(app.FigureNeuro,'Tag','Box');
  768. flip_color = flip(bar_color);
  769. for j=1:length(h3)
  770. patch(app.FigureNeuro,get(h3(j),'XData'),get(h3(j),'YData'),flip_color(j,:),'EdgeColor','none');
  771. end
  772. hold(app.FigureNeuro, 'on');
  773. h2 = boxplot(app.FigureNeuro, vals_plot,'widths',0.9,'outliersize',2,'Colors',zeros(3,3));
  774. set(h2(7,:),'Visible','off');
  775. lines = findobj(app.FigureNeuro, 'type', 'line', 'Tag', 'Median');
  776. set(lines, 'Color', 'black');
  777. grid(app.FigureNeuro,'on');
  778. end
  779. Rec_list = Results.Resh(2:end,1);
  780. app.FigureNeuro.XTick = 1:length(Rec_list);
  781. if length(Results.filesPET)>1
  782. app.FigureNeuro.XTickLabel = Rec_list;
  783. app.FigureNeuro.FontSize = 16;
  784. app.FigureNeuro.XTickLabelRotation = 90;
  785. else
  786. app.FigureNeuro.XTickLabel = Rec_list;
  787. app.FigureNeuro.FontSize = 16;
  788. end
  789. vv = vals_plot';
  790. vv2 = vv(:);
  791. hold(app.FigureNeuro, 'on');
  792. for i = 1:length(Results.filesPET)
  793. if size(Results.data,1)==1
  794. set(h2(i),'facecolor',bar_color(i,:),'edgecolor','none');
  795. end
  796. if opt_comp>=4
  797. if n_files>1
  798. plot(app.FigureNeuro, x_n_n(ind_plot==i),vv2(ind_plot==i),'o','MarkerSize',8,'MarkerFaceColor',bar_color(i,:),'MarkerEdgeColor','black','LineWidth',1);
  799. end
  800. end
  801. end
  802. if opt_comp~=4 && opt_comp ~= 7
  803. if exist('h_sig','var')
  804. ind_sig = find(h_sig);
  805. ind_sig = ind_sig(ind_sig<=max(app.FigureNeuro.XTick));
  806. if ~exist('max_m_x','var')
  807. max_m_x = max(vals_plot(:));
  808. min_m_x = min(vals_plot(:));
  809. end
  810. % Add asterisks+
  811. for i = 1:length(ind_sig)
  812. text(app.FigureNeuro,ind_sig(i), max_m_x+0.04, '*', ...
  813. 'HorizontalAlignment', 'center',...
  814. 'FontSize', 40, 'FontWeight', 'bold');
  815. end
  816. ylim(app.FigureNeuro,[min_m_x.*1.1 max_m_x+0.20]);
  817. end
  818. end
  819. app.FigureNeuro.YLimMode = 'manual';
  820. opt_ana = Results.options(2);
  821. switch opt_ana
  822. case 1
  823. ylabel(app.FigureNeuro,'Fisher''s z (Spearman rho)','fontweight','bold');
  824. case 2
  825. ylabel(app.FigureNeuro,'Fisher''s z (Pearson r)','fontweight','bold');
  826. case 3
  827. ylabel(app.FigureNeuro,'Standardized beta coeffiecient','fontweight','bold');
  828. end
  829. app.FigureNeuro.Color = 'white';
  830. hold(app.FigureNeuro, 'off');
  831. end
  832. function scatter_plot(app)
  833. cla(app.FigureNeuro, 'reset');
  834. opt_ana = app.Results.options(1);
  835. data_list = app.Results.set1_images;
  836. data_all = app.Results.data;
  837. All_PET = app.xaxisList.Items;
  838. Selected_PET = app.xaxisList.Value;
  839. [~, ind_sel] = ismember(Selected_PET, All_PET);
  840. if size(data_all,1)>1
  841. selected_data = app.yaxisList.Value;
  842. ind_sel_data = find(ismember(data_list, selected_data));
  843. else
  844. ind_sel_data = 1;
  845. end
  846. Rec_list_all = app.Results.Resh(2:end,:);
  847. Rec_list = Rec_list_all(ind_sel);
  848. data_PET = app.Results.data_PET(ind_sel,:);
  849. colors = generate_colors_nice_my(size(data_PET,1));
  850. data = data_all(ind_sel_data,:);
  851. opt_rank = app.RankPlotCheckBox.Value;
  852. hold(app.FigureNeuro, 'on');
  853. % plot first one only
  854. for j = 1:size(data_PET,1)
  855. xx = removenan_my([data_PET(j,:)' data(1,:)']);
  856. x = xx(:,1);
  857. y = xx(:,2);
  858. if opt_rank == 1
  859. x = tiedrank(x);
  860. y = tiedrank(y);
  861. end
  862. plot(app.FigureNeuro,x,y,'o','MarkerSize',9,'MarkerFaceColor',colors(j,:),'MarkerEdgeColor','black');
  863. end
  864. % plot remaining
  865. for j = 1:size(data_PET,1)
  866. for i = 2:size(data,1)
  867. xx = removenan_my([data_PET(j,:)' data(i,:)']);
  868. x = xx(:,1);
  869. y = xx(:,2);
  870. if opt_rank == 1
  871. x = tiedrank(x);
  872. y = tiedrank(y);
  873. end
  874. plot(app.FigureNeuro,x,y,'o','MarkerSize',9,'MarkerFaceColor',colors(j,:),'MarkerEdgeColor','black');
  875. end
  876. end
  877. for j = 1:size(data_PET,1)
  878. for i = 1:size(data,1)
  879. xx = removenan_my([data_PET(j,:)' data(i,:)']);
  880. x = xx(:,1);
  881. y = xx(:,2);
  882. if opt_rank == 1
  883. x = tiedrank(x);
  884. y = tiedrank(y);
  885. end
  886. mx = min(x);
  887. Mx = max(x);
  888. my = min(y);
  889. My = max(y);
  890. limx = max([abs(mx) abs(Mx)]);
  891. low_x = prctile(x,5);
  892. high_x = prctile(y,95);
  893. xfit = mx:0.1:Mx;
  894. [p,dev,STATS] = glmfit(x, y);
  895. [yfit,dlo,dhi] = glmval(p,xfit,'identity',STATS,0.95);
  896. set(app.FigureNeuro,'fontsize',18);
  897. DELTA_max = yfit + dlo;
  898. DELTA_min = yfit - dhi;
  899. y_area =[DELTA_min', fliplr(DELTA_max')];
  900. x_area= [xfit, fliplr(xfit)];
  901. faceAlpha = 0.2;
  902. plot(app.FigureNeuro, xfit, yfit, 'r-', 'LineWidth', 2,'color',colors(j,:));
  903. patch(app.FigureNeuro,x_area,y_area,1,'facecolor',colors(j,:),'edgecolor','none','facealpha',faceAlpha);
  904. end
  905. end
  906. grid(app.FigureNeuro,'on');
  907. if opt_rank == 1
  908. xlabel(app.FigureNeuro,'Rank data PET)','FontSize',16);
  909. ylabel(app.FigureNeuro,'Rank data modality','FontSize',16);
  910. else
  911. ylabel(app.FigureNeuro,'Data modality','FontSize',16);
  912. xlabel(app.FigureNeuro,'Data PET','FontSize',16);
  913. end
  914. legend_plot = Rec_list;
  915. legend(app.FigureNeuro, legend_plot,'AutoUpdate','off','Location','southeast');
  916. end
  917. function [name_save_new] = add_suffix(name_save,options)
  918. file_part = '';
  919. switch options(1)
  920. case 1
  921. file_part = [file_part '_ESb'];
  922. case 2
  923. file_part = [file_part '_ESw'];
  924. case 3
  925. file_part = [file_part '_mList1'];
  926. case 4
  927. file_part = [file_part '_List1Each'];
  928. case 5
  929. file_part = [file_part '_indZ'];
  930. case 6
  931. file_part = [file_part '_pwDiff'];
  932. case 7
  933. file_part = [file_part '_looList1'];
  934. case 8
  935. file_part = [file_part '_List1EachGroupTest'];
  936. end
  937. switch options(2)
  938. case 1
  939. file_part = [file_part '_Spearman'];
  940. case 2
  941. file_part = [file_part '_Pearson'];
  942. case 3
  943. file_part = [file_part '_multReg'];
  944. end
  945. if options(3) == 1
  946. file_part = [file_part '_withExactP'];
  947. end
  948. if options(5) == 1
  949. file_part = [file_part '_withExactSpatialP'];
  950. end
  951. time_now = datestr(datetime('now'),'ddmmmyyyy_HHMMSS');
  952. name_save_new = [name_save file_part '_' time_now];
  953. end

JuSpace.m at commit 99c08a8, no license · at the source

Overview

Authors: Hu-Cheng Yang1,2, Si-Jia Bian1, Xi-Lei Gao2, Feng-Mei Zhang2, Ping-Lei Pan3,4, Wen-Hui Li1,5, Zhen-Yu Dai1, Si-Yu Gu1
  1. Department of Radiology, The Yancheng School of Clinical Medicine of Nanjing Medical University, Yancheng Third People’s Hospital, Yancheng, China
  2. Binhai Maternal and Child Health Hospital, Yancheng, China
  3. Department of Neurology, The Yancheng School of Clinical Medicine of Nanjing Medical University, Yancheng Third People’s Hospital, Yancheng, China
  4. Department of Central Laboratory, The Yancheng School of Clinical Medicine of Nanjing Medical University, Yancheng Third People’s Hospital, Yancheng, China
  5. Yancheng Maternal and Child Health Care Hospital Affiliated to Yangzhou University, Yancheng, China
Journal: Frontiers in neurology, volume 17, article 1796739
Dates: received 27 January 2026; accepted 18 August 2026; published online 3 September 2026
Type: Systematic review · Language: English
License: CC BY
Identifiers: DOI 10.3389/fneur.2026.1796739 · PMID 42755892 · PMCID PMC13581937 · OpenAlex W7207704523
Open access: gold, a free copy (OpenAlex)
Status: code verified
Categories: fMRI (modality), human (organism), pain (population)
Methods: Spectral & time-frequency, Statistics, Connectivity, fMRI & imaging
Keywords: functional connectivity network mapping, migraine, network localization, resting-state fMRI, visual network
MeSH: Brain*, Connectome*, Migraine Disorders*, Nerve Net*, Humans, Magnetic Resonance Imaging (* major topic)
Topic: Migraine and Headache Studies (Psychiatry and Mental health, Medicine), according to OpenAlex
Funding: Jiangsu Commission of Health
Citations: not cited yet (Europe PMC); 160 references in the paper

Abstract

Background: Migraine is a prevalent and disabling neurological disorder. Resting-state functional magnetic resonance imaging (rs-fMRI) studies have investigated regional intrinsic neural activity alterations in migraine but have often yielded inconsistent findings. Emerging network perspectives suggest that brain disorders may be better understood through disruptions in large-scale networks.

Methods: This systematic review included 31 rs-fMRI studies (1,238 migraine patients; 1,005 controls; 302 altered ALFF/ReHo coordinates) to clarify these discrepancies. Using functional connectivity network mapping (FCNM) with Human Connectome Project data (n = 1,093), we identified that heterogeneous regional intrinsic neural activity alterations in migraine converge onto common brain functional networks. Spatial relationships between the identified brain networks and the distribution of major neurotransmitter receptors/transporters were subsequently characterized using the Juspace toolbox.

Results: FCNM analysis revealed that heterogeneous regional intrinsic neural activity alterations reported in migraine studies mapped to common brain functional networks, particularly within visual, somatomotor, and attention systems. The FCNM-identified migraine network exhibited significant spatial correlations with normative distributions of metabotropic glutamate receptor 5 (mGluR5), 5-hydroxytryptamine receptor 2A (5-HT2A), and noradrenaline transporter (NAT).

Conclusion: These findings suggest that intrinsic neural dysfunctions in migraine map to large-scale networks with multi-neurochemical susceptibility. This framework suggests that heterogeneous regional intrinsic activity alterations in migraine are preferentially connected to visual, somatomotor, and attentional systems and are spatially aligned with normative neurochemical maps. These findings are hypothesis-generating and should not be interpreted as evidence of causality or patient-specific receptor alterations.

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

Repository

Its files are read in the Code ↔ Paper reader above.

juryxy/JuSpace

License: none: the authors keep all their rights
State: the link answers, verified on 26 September 2026
Evidence: files inventoried
Commit: 99c08a889b292d1f28a89aa12df25663243f16c8, 8 June 2026
Languages: MATLAB (19), Shell (1)
Size: 182 files, 20 scripts
Software Heritage: not archived
Found in: the end of the paper
Holds: README
Not found: license file, CITATION.cff, environment file, tests, continuous integration, documentation
Availability: 1 check, the latest on 26 September 2026: the link answers
  • 26 September 2026: the link answers
21 files

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;
  • 20 scripts, each with its path and the digest of its content;
  • no match between paragraphs and code yet;
  • 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

Datasets cited

Data availability statement

The original contributions presented in the study are included in the article/Supplementary material, further inquiries can be directed to the corresponding authors.

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 3, 28 September 2026

  • Funding: added Jiangsu Commission of Health

Version 1, 27 September 2026: the first record

Recorded: type, language, journal, volume, pages, dates, 8 authors, 5 keywords, 6 MeSH terms, 157 references.

Cite

This paper

Yang, H.-C., Bian, S.-J., Gao, X.-L., Zhang, F.-M., Pan, P.-L., Li, W.-H., Dai, Z.-Y., & Gu, S.-Y. (2026). Network localization of regional intrinsic neural activity alterations in migraine and their neurochemical correlates. Frontiers in neurology, 17, 1796739. https://doi.org/10.3389/fneur.2026.1796739

BibTeX

@article{yang2026network,
author = {Yang, Hu-Cheng and Bian, Si-Jia and Gao, Xi-Lei and Zhang, Feng-Mei and Pan, Ping-Lei and Li, Wen-Hui and Dai, Zhen-Yu and Gu, Si-Yu},
title = {{Network localization of regional intrinsic neural activity alterations in migraine and their neurochemical correlates}},
journal = {Frontiers in neurology},
year = {2026},
month = sep,
volume = {17},
pages = {1796739},
publisher = {Frontiers Media SA},
issn = {1664-2295},
doi = {10.3389/fneur.2026.1796739},
url = {https://doi.org/10.3389/fneur.2026.1796739},
pmid = {42755892},
pmcid = {PMC13581937}
}

RIS

TY - JOUR
AU - Yang, Hu-Cheng
AU - Bian, Si-Jia
AU - Gao, Xi-Lei
AU - Zhang, Feng-Mei
AU - Pan, Ping-Lei
AU - Li, Wen-Hui
AU - Dai, Zhen-Yu
AU - Gu, Si-Yu
TI - Network localization of regional intrinsic neural activity alterations in migraine and their neurochemical correlates
T2 - Frontiers in neurology
J2 - Front Neurol
PY - 2026
DA - 2026/09/03
VL - 17
SP - 1796739
SN - 1664-2295
PB - Frontiers Media SA
DO - 10.3389/fneur.2026.1796739
UR - https://doi.org/10.3389/fneur.2026.1796739
LA - en
ER -

CSL-JSON

{
"id": "10.3389/fneur.2026.1796739",
"type": "article-journal",
"title": "Network localization of regional intrinsic neural activity alterations in migraine and their neurochemical correlates",
"container-title": "Frontiers in neurology",
"author": [
{
"family": "Yang",
"given": "Hu-Cheng"
},
{
"family": "Bian",
"given": "Si-Jia"
},
{
"family": "Gao",
"given": "Xi-Lei"
},
{
"family": "Zhang",
"given": "Feng-Mei"
},
{
"family": "Pan",
"given": "Ping-Lei"
},
{
"family": "Li",
"given": "Wen-Hui"
},
{
"family": "Dai",
"given": "Zhen-Yu"
},
{
"family": "Gu",
"given": "Si-Yu"
}
],
"container-title-short": "Front Neurol",
"volume": "17",
"page": "1796739",
"DOI": "10.3389/fneur.2026.1796739",
"PMID": "42755892",
"PMCID": "PMC13581937",
"ISSN": "1664-2295",
"publisher": "Frontiers Media SA",
"URL": "https://doi.org/10.3389/fneur.2026.1796739",
"language": "en",
"issued": {
"date-parts": [
[
2026,
9,
3
]
]
}
}

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.3389/fnmol.2026.1909269 [code]
Convergent functional networks of intrinsic activity alterations in temporal lobe epilepsy and their molecular correlates.
Journal: Frontiers in molecular neuroscience
In common: fdr_bh (Benjamini-Hochberg FDR), SPM, Statistics and Machine Learning Toolbox, humanconnectome.org/study/hcp-young-adult, fMRI, 14 references
[2] doi:10.1017/s0033291726103924 [code]
Brain network representations of placebo analgesia.
Journal: Psychological medicine
In common: SPM, pain, fMRI, 14 references
[3] doi:10.1038/s41598-026-53726-7 [code]
Integrated anatomical and functional connectivity mapping in episodic migraine: a spectral graph theory approach.
Journal: Scientific reports
In common: Statistics and Machine Learning Toolbox, pain, fMRI, 4 references
[4] doi:10.1038/s41586-026-10631-3 [code]
A prognostic human brain network for diffuse midline glioma.
Journal: Nature
In common: SPM, Statistics and Machine Learning Toolbox, 5 references
[5] doi:10.1002/hbm.70483 [code]
Untamed: Unconstrained Tensor Decomposition and Graph Node Embedding for Cortical Parcellation.
Journal: Human brain mapping
In common: SPM, Statistics and Machine Learning Toolbox, humanconnectome.org/study/hcp-young-adult, fMRI, 2 references
[6] doi:10.1007/s10548-026-01247-x [code]
Salience Network Dynamics Across Spontaneous Attacks, Interictal Rest and Interictal Pain Imagery in Menstrually Related Migraine.
Journal: Brain topography
In common: Statistics and Machine Learning Toolbox, pain, fMRI, 4 references
[7] doi:10.1038/s41531-026-01388-7 [code]
Converging metabolic and functional networks for tremor expression and deep brain stimulation-mediated control.
Journal: NPJ Parkinson's disease
In common: SPM, 5 references
[8] doi:10.1093/braincomms/fcag316 [code]
Structural, functional and neurochemical imaging mapping of non-motor symptoms in Parkinson's disease.
Journal: Brain communications
In common: 6 references
[9] doi:10.1038/s41398-026-04073-8 [code]
Functional connectivity density alterations in obsessive-compulsive disorder are associated with neurotransmitter and genetic profiles.
Journal: Translational psychiatry
In common: fdr_bh (Benjamini-Hochberg FDR), SPM, Statistics and Machine Learning Toolbox, 3 references
[10] doi:10.1016/j.neuroimage.2026.122171 [code]
A conserved node degree-based backbone and flexible hub organization of brain connectome during naturalistic movie watching.
Journal: NeuroImage
In common: SPM, Statistics and Machine Learning Toolbox, humanconnectome.org/study/hcp-young-adult, fMRI, 1 reference

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.