OSCR

Prenatal and early postnatal periods differentially shape the maturation of human cortical microstructure and myelin.

Code ↔ Paper

4 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 4 matches · 1 of them tie a paragraph to a whole file without given lines: a weak match, whose lines are not tinted
  1. [1] § Methods › MRI acquisition and preprocessing ↔ code/infant_micro_figures.m, lines 93 to 142 · score 0.67 · parcellated cortical, von Economo, cortical thickness, hemisphere, validation, Schaefer · Report a mismatch
  2. [2] § Methods › Microstructure profiles and their central moments ↔ code/infant_micro_figures.m, lines 93 to 142 · score 0.57 · left hemisphere, microstructure profiles, von Economo, scans, vertex, week · Report a mismatch
  3. [3] § Methods › Participants and demographics ↔ code/infant_micro_figures.m, lines 144 to 212 · score 0.53 · postmenstrual age, gestational age, singleton, scans, birth, infants · Report a mismatch
  4. [4] § Methods › Statistical analysis ↔ code/moment_age_model.m, the whole file · a weak match · score 0.51 · response variable, linear model, validating, predictors, metrics, thickness · Report a mismatch

Paper

Loaded from Europe PMC by your browser; OSCR does not store it: doi.org · Europe PMC

The paper is loaded when this pane is shown.

The authors' code

MATLAB · 1,969 lines · 104 KB · no license · 3 matches

  1. for init_project = 1
  2. GH = '/Users/ttsigaras/Documents/GitHub'; % GitHub directory
  3. homeDir = [GH '/InfantMicro'];
  4. % directory of each participant's native microstructure profile csv
  5. MPs_dir = [homeDir '/data/native_MPs'];
  6. % directory of vertex-wise Von Economo parcel indices
  7. labels_dir_economo = [homeDir '/data/native_economo_ind'];
  8. % directory of vertex-wise Schaefer-200 parcel indices
  9. labels_dir_schaefer200 = [homeDir '/data/native_schaefer200_ind'];
  10. % directory of parcel-wise (Von Economo) cortical thickness
  11. thick_dir = [homeDir '/data/native_thick_economo'];
  12. wk40_tpl_dir = [homeDir '/tpl-week-40']; % week-40 template directory
  13. % add paths for GitHub directories (gifti toolbox and scripts)
  14. addpath(genpath([homeDir '/code']))
  15. addpath(genpath([GH '/gifti']))
  16. % load demographic data
  17. demographics = readtable([homeDir '/data/nnsi01.txt']); % load demographics file
  18. depths = 1:12; % number of depths per profile
  19. % defining valid parcels for each parcellation. Von Economo's
  20. % parcellation includes Corpus Callosum parcels (#2 and #47), which are
  21. % not assigned to any vertex, therefore although the official parcellation
  22. % includes 90 parcels, there are only 88 unique parcel indices when
  23. % extracting the unique indices from the label files. The below defined
  24. % parcels indices are actually the positions of the parcels within the
  25. % total number of parcels and not the actual indices
  26. total_num_parcels_economo = 88;
  27. total_num_parcels_schaefer200 = 201;
  28. excluded_indices_economo = [1, 15, 16, 17, 20, 21, 22, 23, 24, 25, 26, 45, ...
  29. 59, 60, 61, 64, 65, 66, 67, 68, 69, 70]; % non-cortical and limbic parcels
  30. valid_parcels_economo = setdiff(1:total_num_parcels_economo, ...
  31. excluded_indices_economo); % cortical and non-limbic parcel
  32. valid_parcels_schaefer200 = 2:201;
  33. % load week-40 pial surface
  34. wk40_lh_pial = gifti([wk40_tpl_dir '/week-40_hemi-left_space-dhcpSym_dens-32k_pial.surf.gii']);
  35. wk40_rh_pial = gifti([wk40_tpl_dir '/week-40_hemi-right_space-dhcpSym_dens-32k_pial.surf.gii']);
  36. wk40.tri = [wk40_lh_pial.faces; wk40_rh_pial.faces + size(wk40_lh_pial.vertices, 1)];
  37. wk40.coord = [wk40_lh_pial.vertices; wk40_rh_pial.vertices]';
  38. % load Von Economo's week-40 tpl vertex-wise parcel indices
  39. wk40_eco_lh_ind = gifti([wk40_tpl_dir '/week-40_hemi-left_desc-economo.label.gii']);
  40. wk40_eco_rh_ind = gifti([wk40_tpl_dir '/week-40_hemi-right_desc-economo.label.gii']);
  41. wk40_economo_ind = [wk40_eco_lh_ind.cdata + 1; wk40_eco_rh_ind.cdata + 46];
  42. % load Schaefer-200's week-40 tpl vertex-wise parcel indices
  43. wk40_sch200_lh_ind = gifti([wk40_tpl_dir '/week-40_hemi-left_desc-Schaefer2018_7Networks_200.32k.label.gii']);
  44. wk40_sch200_rh_ind = gifti([wk40_tpl_dir '/week-40_hemi-right_desc-Schaefer2018_7Networks_200.32k.label.gii']);
  45. wk40_schaefer200_ind = [wk40_sch200_lh_ind.cdata; wk40_sch200_rh_ind.cdata];
  46. % load colour maps
  47. load([homeDir '/resources/colourmaps/colorbrewer.mat'])
  48. scicol = [homeDir '/resources/colourmaps/ScientificColourMaps7'];
  49. scicol_names = ["devon", "lajolla", "lapaz", "roma", "vik"];
  50. for ii = 1:length(scicol_names)
  51. load(strcat(scicol, '/', scicol_names(ii), '.mat'));
  52. end
  53. % load eigenmodes 2, 3 and 4
  54. eigenmodes = readmatrix([homeDir '/resources/week-40_pial_hemi-left_emode_2-4.txt']);
  55. % load previously used permutation indices
  56. load([homeDir '/resources/spin_test_ind_wk40.mat'], 'perm_id')
  57. end
  58. for preparing_data = 1
  59. variables = {'src_subject_id', 'scan_validation', 'nscan_ga_at_birth_weeks', ...
  60. 'nscan_ga_at_scan_weeks', 'sex'};
  61. filt_demographics = table();
  62. for sub = 1:height(demographics)
  63. sub_id = demographics.src_subject_id{sub}; % subject ID
  64. ses_id = num2str(demographics.scan_validation(sub)); % session ID
  65. MP_file_dir = fullfile(MPs_dir, [sub_id '_ses-' ses_id '_desc-MP.csv']);
  66. left_label_file_dir_economo = fullfile(labels_dir_economo, [sub_id ...
  67. '_ses-' ses_id '_hemi-left_desc-economo.label.gii']);
  68. right_label_file_dir_economo = fullfile(labels_dir_economo, [sub_id ...
  69. '_ses-' ses_id '_hemi-right_desc-economo.label.gii']);
  70. % if all 3 files exist, add subject to the filtered table
  71. if isfile(MP_file_dir) && isfile(left_label_file_dir_economo) && ...
  72. isfile(right_label_file_dir_economo)
  73. filt_demographics = [filt_demographics; demographics(sub, variables)];
  74. else
  75. fprintf('Missing files for sub-%s_ses-%s.\n', sub_id, ses_id);
  76. end
  77. end
  78. % remove subsequent scans of longitudinal participants
  79. filt_demographics.scan_validation = double(filt_demographics.scan_validation);
  80. filt_demographics = sortrows(filt_demographics, ...
  81. {'src_subject_id', 'scan_validation'});
  82. [~, first_idx] = unique(filt_demographics.src_subject_id, 'stable');
  83. filt_demographics = filt_demographics(first_idx, :);
  84. filt_demographics.postnatal_age = filt_demographics.nscan_ga_at_scan_weeks ...
  85. - filt_demographics.nscan_ga_at_birth_weeks; % calculate postnatal age at scan
  86. % excluding participants with PNA > 7
  87. filt_demographics(filt_demographics.postnatal_age > 7, :) = [];
  88. MP_parc_economo = nan(length(depths), total_num_parcels_economo, height(filt_demographics));
  89. MP_parc_schaefer200 = nan(length(depths), total_num_parcels_schaefer200, height(filt_demographics));
  90. thick_parc_economo = nan(total_num_parcels_economo, height(filt_demographics));
  91. for sub = 1:height(filt_demographics)
  92. sub_id = filt_demographics.src_subject_id{sub}; % subject ID
  93. ses_id = num2str(filt_demographics.scan_validation(sub)); % session ID
  94. MP_file_dir = fullfile(MPs_dir, [sub_id '_ses-' ses_id '_desc-MP.csv']);
  95. thick_file_dir = fullfile(thick_dir, [sub_id '_ses-' ses_id '_desc-thickness_parc-economo.csv']);
  96. left_label_file_dir_economo = fullfile(labels_dir_economo, ...
  97. [sub_id '_ses-' ses_id '_hemi-left_desc-economo.label.gii']);
  98. right_label_file_dir_economo = fullfile(labels_dir_economo, ...
  99. [sub_id '_ses-' ses_id '_hemi-right_desc-economo.label.gii']);
  100. left_label_file_dir_schaefer200 = fullfile(labels_dir_schaefer200, ...
  101. [sub_id '_ses-' ses_id '_hemi-left_desc-Schaefer2018_7Networks_200.32k.label.gii']);
  102. right_label_file_dir_schaefer200 = fullfile(labels_dir_schaefer200, ...
  103. [sub_id '_ses-' ses_id '_hemi-right_desc-Schaefer2018_7Networks_200.32k.label.gii']);
  104. MP = readmatrix(MP_file_dir); % read microstructure profiles
  105. sub_thick_parc = readmatrix(thick_file_dir); % read parcellated cortical thickness
  106. left_labels_economo = gifti(left_label_file_dir_economo);
  107. right_labels_economo = gifti(right_label_file_dir_economo);
  108. left_labels_schaefer200 = gifti(left_label_file_dir_schaefer200);
  109. right_labels_schaefer200 = gifti(right_label_file_dir_schaefer200);
  110. left_ind_economo = left_labels_economo.cdata;
  111. % add 45 to the right hemisphere parcel indices to differentiate them from the left hemisphere ones
  112. right_ind_economo = right_labels_economo.cdata + 45;
  113. left_ind_schaefer200 = left_labels_schaefer200.cdata;
  114. right_ind_schaefer200 = right_labels_schaefer200.cdata;
  115. economo_ind = cat(1, left_ind_economo, right_ind_economo); % vertex-wise Von Economo parcel indices
  116. schaefer200_ind = cat(1, left_ind_schaefer200, right_ind_schaefer200); % vertex-wise Schaefer-200 parcel indices
  117. num_of_parc_economo = unique(economo_ind);
  118. num_of_parc_schaefer200 = unique(schaefer200_ind);
  119. if length(num_of_parc_economo) == 88
  120. if length(num_of_parc_schaefer200) == 201
  121. sub_MP_parc_economo = zeros(size(MP, 1), length(num_of_parc_economo));
  122. sub_MP_parc_schaefer200 = zeros(size(MP, 1), length(num_of_parc_schaefer200));
  123. MP(isinf(MP)) = NaN;
  124. % calculate the average intensity per parcel at each depth
  125. for depth = 1:size(MP, 1)
  126. sub_MP_parc_economo(depth,:) = grpstats(MP(depth,:) , economo_ind);
  127. sub_MP_parc_schaefer200(depth,:) = grpstats(MP(depth,:) , schaefer200_ind);
  128. end
  129. MP_parc_economo(:,:,sub) = sub_MP_parc_economo;
  130. MP_parc_schaefer200(:,:,sub) = sub_MP_parc_schaefer200;
  131. thick_parc_economo(:,sub) = sub_thick_parc;
  132. else
  133. fprintf('Subject %s session %s has wrong number of Schaefer parcels.\n', sub_id, ses_id);
  134. end
  135. else
  136. fprintf('Subject %s session %s has wrong number of Von Economo parcels.\n', sub_id, ses_id);
  137. end
  138. end
  139. moments_parc_economo = NaN(5, total_num_parcels_economo, size(MP_parc_economo, 3));
  140. moments_parc_schaefer200 = NaN(5, total_num_parcels_schaefer200, size(MP_parc_schaefer200, 3));
  141. for sub = 1:height(filt_demographics)
  142. MP_economo = MP_parc_economo(:, :, sub);
  143. MP_schaefer200 = MP_parc_schaefer200(:, :, sub);
  144. MP_economo = round(MP_economo*100); % required for the calculate_moments() function to work
  145. MP_schaefer200= round(MP_schaefer200*100); % required for the calculate_moments() function to work
  146. % calculate the moments of this profile
  147. moments_economo = calculate_moments(MP_economo);
  148. moments_schaefer200 = calculate_moments(MP_schaefer200);
  149. moments_parc_economo(:, :, sub) = moments_economo;
  150. moments_parc_schaefer200(:, :, sub) = moments_schaefer200;
  151. end
  152. moments_parc_economo(1,:,:) = moments_parc_economo(1,:,:)/100;
  153. moments_parc_schaefer200(1,:,:) = moments_parc_schaefer200(1,:,:)/100;
  154. % exclude mean intensity, skewness and kurtosis from the moments
  155. moments_parc_economo([1 4 5], :, :) = [];
  156. moments_parc_schaefer200([1 4 5], :, :) = [];
  157. % exclude twins. Twins/Triples have the string "AN", "BN", "CN"
  158. % following the number in their subject ID, whereas singleton infants
  159. % have the string "XX"
  160. ids = string(filt_demographics.src_subject_id);
  161. expression = "CC(?<group>\d{5})(?<twin_id>[A-Z]{2})";
  162. tokens = regexp(ids, expression, 'names');
  163. tokens = vertcat(tokens{:});
  164. twin_id = string({tokens.twin_id}');
  165. is_twin = twin_id ~= "XX";
  166. filt_demographics_no_twins = filt_demographics(~is_twin,:);
  167. moments_parc_no_twins = moments_parc_economo(:,:,~is_twin);
  168. MP_parc_no_twins = MP_parc_economo(:,:,~is_twin);
  169. end
  170. for creating_gen_table = 1
  171. GA = filt_demographics.nscan_ga_at_birth_weeks; % gestational age [weeks]
  172. PNA = filt_demographics.postnatal_age; % postnatal age at scan [weeks]
  173. PMA = filt_demographics.nscan_ga_at_scan_weeks; % postmenstrual age at scan [weeks]
  174. sex = filt_demographics.sex; % sex
  175. sub_id = filt_demographics.src_subject_id; % subject ID
  176. ses_id = filt_demographics.scan_validation; % session ID
  177. GA_no_twins = filt_demographics_no_twins.nscan_ga_at_birth_weeks; % gestational age [weeks]
  178. PNA_no_twins = filt_demographics_no_twins.postnatal_age; % postnatal age at scan [weeks]
  179. PMA_no_twins = filt_demographics_no_twins.nscan_ga_at_scan_weeks; % postmenstrual age at scan [weeks]
  180. sex_no_twins = filt_demographics_no_twins.sex; % sex
  181. sub_id_no_twins = filt_demographics_no_twins.src_subject_id; % subject ID
  182. ses_id_no_twins = filt_demographics_no_twins.scan_validation; % session ID
  183. num_subjects = size(filt_demographics, 1);
  184. num_subjects_no_twins = size(filt_demographics_no_twins, 1);
  185. % repeating entries, in order to match the number of parcels per subject
  186. sub_id_rep_economo = repelem(sub_id, total_num_parcels_economo, 1);
  187. ses_id_rep_economo = repelem(ses_id, total_num_parcels_economo, 1);
  188. GA_rep_economo = repelem(GA, total_num_parcels_economo, 1);
  189. PNA_rep_economo = repelem(PNA, total_num_parcels_economo, 1);
  190. PMA_rep_economo = repelem(PMA, total_num_parcels_economo, 1);
  191. sex_rep_economo = repelem(sex, total_num_parcels_economo, 1);
  192. sub_id_rep_no_twins = repelem(sub_id_no_twins, total_num_parcels_economo, 1);
  193. ses_id_rep_no_twins = repelem(ses_id_no_twins, total_num_parcels_economo, 1);
  194. GA_rep_no_twins = repelem(GA_no_twins, total_num_parcels_economo, 1);
  195. PNA_rep_no_twins = repelem(PNA_no_twins, total_num_parcels_economo, 1);
  196. PMA_rep_no_twins = repelem(PMA_no_twins, total_num_parcels_economo, 1);
  197. sex_rep_no_twins = repelem(sex_no_twins, total_num_parcels_economo, 1);
  198. sub_id_rep_schaefer200 = repelem(sub_id, total_num_parcels_schaefer200, 1);
  199. ses_id_rep_schaefer200 = repelem(ses_id, total_num_parcels_schaefer200, 1);
  200. GA_rep_schaefer200 = repelem(GA, total_num_parcels_schaefer200, 1);
  201. PNA_rep_schaefer200 = repelem(PNA, total_num_parcels_schaefer200, 1);
  202. PMA_rep_schaefer200 = repelem(PMA, total_num_parcels_schaefer200, 1);
  203. sex_rep_schaefer200 = repelem(sex, total_num_parcels_schaefer200, 1);
  204. % multiplying the parcel indices with the number of subjects
  205. parcel_id_rep_economo = repmat(unique(wk40_economo_ind), num_subjects, 1);
  206. parcel_id_rep_no_twins = repmat(unique(wk40_economo_ind), num_subjects_no_twins, 1);
  207. parcel_id_rep_schaefer200 = repmat(unique(wk40_schaefer200_ind), num_subjects, 1);
  208. % reshaping the moments and cortical thickness to match the table's structure
  209. moments_rep_economo = reshape(moments_parc_economo, [2, total_num_parcels_economo * num_subjects])';
  210. thickness_rep = reshape(thick_parc_economo, [total_num_parcels_economo * num_subjects,1]);
  211. moments_rep_no_twins = reshape(moments_parc_no_twins, [2, total_num_parcels_economo * num_subjects_no_twins])';
  212. moments_rep_schaefer200 = reshape(moments_parc_schaefer200, [2, total_num_parcels_schaefer200 * num_subjects])';
  213. % creating the tables
  214. gen_table_economo = table(sub_id_rep_economo, ses_id_rep_economo, GA_rep_economo, ...
  215. PMA_rep_economo, PNA_rep_economo, sex_rep_economo, parcel_id_rep_economo, ...
  216. thickness_rep, moments_rep_economo(:,1), moments_rep_economo(:,2), ...
  217. 'VariableNames', {'subject_id', 'session_id', 'GA', 'PMA', 'PNA', ...
  218. 'sex', 'parcel', 'thick', 'cog', 'variance'});
  219. gen_table_no_twins = table(sub_id_rep_no_twins, ses_id_rep_no_twins, ...
  220. GA_rep_no_twins, PMA_rep_no_twins, PNA_rep_no_twins, sex_rep_no_twins, ...
  221. parcel_id_rep_no_twins, moments_rep_no_twins(:,1), moments_rep_no_twins(:,2), ...
  222. 'VariableNames', {'subject_id', 'session_id', 'GA', 'PMA', 'PNA', ...
  223. 'sex', 'parcel', 'cog', 'variance'});
  224. gen_table_schaefer200 = table(sub_id_rep_schaefer200, ses_id_rep_schaefer200, ...
  225. GA_rep_schaefer200, PMA_rep_schaefer200, PNA_rep_schaefer200, sex_rep_schaefer200, ...
  226. parcel_id_rep_schaefer200, moments_rep_schaefer200(:,1), moments_rep_schaefer200(:,2), ...
  227. 'VariableNames', {'subject_id', 'session_id', 'GA', 'PMA', 'PNA', ...
  228. 'sex', 'parcel', 'cog', 'variance'});
  229. % parcels to exclude from the Von Economo general table
  230. % (i.e. cortical wall, limbic and hippocampal lobes)
  231. exclude_parcels = [1, 16, 17, 18, 21, 22, 23, 24, 25, 26, 27, ...
  232. 46, 61, 62, 63, 66, 67, 68, 69, 70, 71, 72];
  233. % excluding subjects with a PNA lower than 7 weeks and also
  234. % parcels belonging to the cortical wall, hippocampal and limbic lobes
  235. gen_table_economo = gen_table_economo(gen_table_economo.PNA <= 7 & ...
  236. ~ismember(gen_table_economo.parcel, exclude_parcels), :);
  237. gen_table_economo.sex = categorical(gen_table_economo.sex); % making sex a categorical variable
  238. gen_table_no_twins = gen_table_no_twins(gen_table_no_twins.PNA <= 7 & ...
  239. ~ismember(gen_table_no_twins.parcel, exclude_parcels), :);
  240. gen_table_no_twins.sex = categorical(gen_table_no_twins.sex); % making sex a categorical variable
  241. gen_table_schaefer200.sex = categorical(gen_table_schaefer200.sex); % making sex a categorical variable
  242. % averaging central moments across subjects
  243. group_vars = {'subject_id', 'session_id', 'GA', 'PMA', 'PNA', 'sex'};
  244. avg_vars1 = {'thick', 'cog', 'variance'};
  245. avg_vars2 = {'cog', 'variance'};
  246. gen_table_avg_economo = groupsummary(gen_table_economo, group_vars, 'mean', avg_vars1);
  247. gen_table_avg_no_twins = groupsummary(gen_table_no_twins, group_vars, 'mean', avg_vars2);
  248. gen_table_avg_schaefer200 = groupsummary(gen_table_schaefer200, group_vars, 'mean', avg_vars2);
  249. for i = 1:numel(avg_vars1)
  250. old_name = ['mean_' avg_vars1{i}];
  251. newName = avg_vars1{i};
  252. gen_table_avg_economo.Properties.VariableNames{old_name} = newName;
  253. end
  254. for i = 1:numel(avg_vars2)
  255. old_name = ['mean_' avg_vars2{i}];
  256. newName = avg_vars2{i};
  257. gen_table_avg_no_twins.Properties.VariableNames{old_name} = newName;
  258. gen_table_avg_schaefer200.Properties.VariableNames{old_name} = newName;
  259. end
  260. gen_table_avg_economo.GroupCount = [];
  261. gen_table_avg_no_twins.GroupCount = [];
  262. gen_table_avg_schaefer200.GroupCount = [];
  263. uparc_economo = unique(gen_table_economo.parcel); % unique Von Economo parcel indices
  264. uparc_schaefer200 = unique(gen_table_schaefer200.parcel); % unique Schaefer-200 parcel indices
  265. uparc_schaefer200(1) = [];
  266. end
  267. for figure_1 = 1
  268. for panel_A = 1
  269. GA = gen_table_avg_economo.GA;
  270. PNA = gen_table_avg_economo.PNA;
  271. PMA = gen_table_avg_economo.PMA;
  272. sex = gen_table_avg_economo.sex;
  273. [~, sort_idx] = sortrows([PMA, PNA]); % sort first by PMA, then by PNA
  274. GA_sorted = GA(sort_idx);
  275. PMA_sorted = PMA(sort_idx);
  276. sex_sorted = sex(sort_idx);
  277. y_vals = 1:length(PMA_sorted);
  278. % plot each participant's age as a line spanning from their time of
  279. % birth to the day of the scan, separately-coloured for each sex
  280. figure('units','centimeters','outerposition',[0 0 56 20]);
  281. hold on;
  282. for i = 1:length(GA_sorted)
  283. if sex_sorted(i) == 'M'
  284. plot([GA_sorted(i), PMA_sorted(i)], [y_vals(i), y_vals(i)], 'Color', lapaz(70,:), 'LineWidth', 0.5);
  285. scatter(GA_sorted(i), y_vals(i), 10, lapaz(70,:), 'filled', 'MarkerEdgeColor', lapaz(70,:));
  286. scatter(PMA_sorted(i), y_vals(i), 10, lapaz(70,:), 'filled', 'MarkerEdgeColor', lapaz(70,:));
  287. elseif sex_sorted(i) == 'F'
  288. plot([GA_sorted(i), PMA_sorted(i)], [y_vals(i), y_vals(i)], 'Color', lajolla(75,:), 'LineWidth', 0.5);
  289. scatter(GA_sorted(i), y_vals(i), 10, lajolla(75,:), 'filled', 'MarkerEdgeColor', lajolla(75,:));
  290. scatter(PMA_sorted(i), y_vals(i), 10, lajolla(75,:), 'filled', 'MarkerEdgeColor', lajolla(75,:));
  291. end
  292. end
  293. set(gca, 'YTick', []);
  294. set(gca, 'FontSize', 14);
  295. xlim([24 max(PMA_sorted)]);
  296. grid off;
  297. hold off;
  298. end
  299. for panel_B = 1
  300. % plot a scatter plot of PNA against GA, coloured by sex
  301. figure('units','centimeters','outerposition',[0 0 21 20]);
  302. hold on;
  303. scatter(gen_table_avg_economo.GA(gen_table_avg_economo.sex == 'F'), ...
  304. gen_table_avg_economo.PNA(gen_table_avg_economo.sex == 'F'), ...
  305. 50, 'filled', 'MarkerFaceColor', lajolla(75,:));
  306. scatter(gen_table_avg_economo.GA(gen_table_avg_economo.sex == 'M'), ...
  307. gen_table_avg_economo.PNA(gen_table_avg_economo.sex == 'M'), ...
  308. 50, 'filled', 'MarkerFaceColor', devon(80,:));
  309. set(gca, 'FontSize', 14);
  310. ylim([0 max(gen_table_avg_economo.PNA)]);
  311. xlim([min(gen_table_avg_economo.GA) max(gen_table_avg_economo.GA)])
  312. grid off;
  313. hold off;
  314. % plot smoothed histograms of PNA and GA distributions
  315. variables = {'GA', 'PNA'};
  316. for i = 1:length(variables)
  317. var = variables{i};
  318. [f1, xi1] = ksdensity(gen_table_avg_economo.(var)(gen_table_avg_economo.sex == 'M'), 'Bandwidth', 0.4);
  319. [f2, xi2] = ksdensity(gen_table_avg_economo.(var)(gen_table_avg_economo.sex == 'F'), 'Bandwidth', 0.4);
  320. figure('units','centimeters','outerposition',[0 0 28 8]);
  321. hold on;
  322. plot(xi1, f1, 'Color', devon(80,:), 'LineWidth', 2);
  323. fill(xi1, f1, devon(80,:), 'FaceAlpha', 0.3);
  324. plot(xi2, f2, 'Color', lajolla(75,:), 'LineWidth', 2);
  325. fill(xi2, f2, lajolla(75,:), 'FaceAlpha', 0.3);
  326. set(gca, 'XTick', [], 'YTick', []);
  327. xlim([min(gen_table_avg_economo.(var)) max(gen_table_avg_economo.(var))]);
  328. grid on;
  329. hold off;
  330. end
  331. end
  332. end
  333. for figure_2 = 1
  334. for panel_A = 1
  335. % calculate and plot the average profile across all participants
  336. % and parcels
  337. depth = 1:12;
  338. avg_profile = mean(MP_parc_economo(:, :, :), [2, 3]);
  339. figure('units','centimeters','outerposition',[0 0 10 22]);
  340. plot(avg_profile, -depth, 'Color', 'k', 'LineWidth', 1.5);
  341. set(gca, 'YTick', []);
  342. set(gca, 'FontSize', 14);
  343. grid off;
  344. end
  345. for panel_B = 1
  346. cmap = flipud(roma);
  347. nsubs = size(MP_parc_economo, 3);
  348. nbins = 100;
  349. for m = 1:2
  350. profiles_reshaped = reshape(MP_parc_economo, [12, ...
  351. total_num_parcels_economo * nsubs]); % reshape profile array
  352. moments_reshaped = reshape(moments_parc_economo(m,:,:), ...
  353. [total_num_parcels_economo * nsubs, 1]); % flatten moment array
  354. if m == 1
  355. % mask profiles based on CoG value
  356. profiles_reshaped = profiles_reshaped(:, ...
  357. moments_reshaped > 5.8); % arbitrary limit for CoG
  358. % assign each profile to a bin based on their CoG value
  359. mom_bins = discretize(moments_reshaped(moments_reshaped > 5.8), ...
  360. nbins); % arbitrary limit for CoG
  361. else
  362. % mask profiles based on variance value
  363. profiles_reshaped = profiles_reshaped(:, ...
  364. moments_reshaped < 3.4); % arbitrary limit for variance
  365. % assign each profile to a bin based on their variance value
  366. mom_bins = discretize(moments_reshaped(moments_reshaped < 3.4), ...
  367. nbins); % arbitrary limit for variance
  368. end
  369. % plot the average profile within each bin
  370. figure('units','centimeters','outerposition',[0 0 10 22]);
  371. hold on;
  372. for ii = 1:nbins
  373. plot(mean(profiles_reshaped(:,mom_bins==ii),2), -depths, ...
  374. 'Color', cmap(round(ii*height(cmap)/100), :), 'LineWidth', 1)
  375. end
  376. colormap(cmap);
  377. set(gca, 'FontSize', 14);
  378. set(gca, 'YTick', []);
  379. grid off;
  380. hold off;
  381. end
  382. end
  383. for panel_C = 1
  384. moment = ["Centre of gravity", "Variance"];
  385. % calculate average moments per parcel
  386. avg_moments = mean(moments_parc_economo, 3);
  387. % replace non-cortical and limbic parcel values with -100 for
  388. % visualisation purposes
  389. avg_moments(:, ~ismember(1:88, valid_parcels_economo)) = -100;
  390. for mom = 1:length(moment)
  391. min_val = min(avg_moments(mom, avg_moments(mom, :) > -100));
  392. min_val = min_val - min_val/100;
  393. vert_avg_moments = BoSurfStatMakeParcelData(avg_moments(mom,:), wk40, wk40_economo_ind);
  394. figure; SurfStatViewData(vert_avg_moments, wk40, strcat(moment(mom)));
  395. colormap([0.7 0.7 0.7; flipud(lajolla)]);
  396. SurfStatColLim([min_val, max(avg_moments(mom,:))]);
  397. end
  398. end
  399. end
  400. for figure_3 = 1
  401. for panel_A =1
  402. moments = ["Centre of gravity", "Variance"];
  403. for mom = 1:length(moments)
  404. if mom == 1
  405. cog_sign_parcel_data_PMA = moment_age_model("cog", "PMA", ...
  406. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 1, 0);
  407. else
  408. var_sign_parcel_data_PMA = moment_age_model("variance", "PMA", ...
  409. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 1, 0);
  410. end
  411. end
  412. % calculate maximum absolute value for limits
  413. min_val = min([min(cog_sign_parcel_data_PMA(cog_sign_parcel_data_PMA > -100)); ...
  414. min(var_sign_parcel_data_PMA(var_sign_parcel_data_PMA > -100))]);
  415. max_val = max([max(cog_sign_parcel_data_PMA(cog_sign_parcel_data_PMA < 100)); ...
  416. max(var_sign_parcel_data_PMA(var_sign_parcel_data_PMA < 100))]);
  417. abs_lim = max(abs(min_val), abs(max_val));
  418. abs_lim = abs_lim + abs_lim/100;
  419. % plot the significant effects of PMA on each moment
  420. for mom = 1:length(moments)
  421. if mom == 1
  422. sign_parc_data_PMA = cog_sign_parcel_data_PMA;
  423. else
  424. sign_parc_data_PMA = var_sign_parcel_data_PMA;
  425. end
  426. sign_vert_data_PMA = BoSurfStatMakeParcelData(sign_parc_data_PMA, wk40, wk40_economo_ind);
  427. figure; SurfStatViewData(sign_vert_data_PMA, wk40, strcat(moments(mom), ' sign. PMA'));
  428. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  429. % SurfStatColLim([-abs_lim, abs_lim]);
  430. % in the manuscript, we use the same colourscale limits as in
  431. % figure 4 for the purpose of comparison. If you want to use
  432. % limits based only on this data, use the line above
  433. SurfStatColLim([-30.8513, 30.8513]); % limits of figure 4
  434. end
  435. end
  436. for panel_B_profile_plots = 1
  437. moments = ["Centre of gravity", "Variance"];
  438. PMA = gen_table_avg_economo.PMA;
  439. min_PMA = min(PMA);
  440. max_PMA = max(PMA);
  441. % define a window size of 1.5 weeks and 50% overlap
  442. window_size = 1.5;
  443. step = 0.75;
  444. ages = min_PMA:step:max_PMA;
  445. for mom = 1:length(moments)
  446. if mom == 1
  447. sign_parcel_data_PMA = moment_age_model("cog", "PMA", ...
  448. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 1, 0);
  449. else
  450. sign_parcel_data_PMA = moment_age_model("variance", "PMA", ...
  451. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 1, 0);
  452. end
  453. % isolate the parcel-indices with the maximum/minimum significant effects
  454. max_change_parc = find(sign_parcel_data_PMA == ...
  455. max(sign_parcel_data_PMA(sign_parcel_data_PMA < 100)));
  456. min_change_parc = find(sign_parcel_data_PMA == ...
  457. min(sign_parcel_data_PMA(sign_parcel_data_PMA > -100)));
  458. % isolate the parcel-indices with the second maximum/minimum significnat effects
  459. sec_max_change_parc = find(sign_parcel_data_PMA == ...
  460. max(sign_parcel_data_PMA(sign_parcel_data_PMA ...
  461. < max(sign_parcel_data_PMA(sign_parcel_data_PMA<100)))));
  462. sec_min_change_parc = find(sign_parcel_data_PMA == ...
  463. min(sign_parcel_data_PMA(sign_parcel_data_PMA ...
  464. > min(sign_parcel_data_PMA(sign_parcel_data_PMA>-100)))));
  465. % isolate the MPs of the parcels with the first/second
  466. % maximum/minimum significant effects
  467. max_change_profs = MP_parc_economo(:,[max_change_parc ...
  468. sec_max_change_parc],:);
  469. min_change_profs = MP_parc_economo(:,[min_change_parc ...
  470. sec_min_change_parc],:);
  471. profiles_to_plot = [max_change_profs min_change_profs];
  472. % plot the profiles of the parcels with the first/second
  473. % maximum/minimum significant effects on CoG
  474. for i = 1:2
  475. profiles = profiles_to_plot(:,i*2-1:i*2,:);
  476. figure('units','centimeters','outerposition',[0 0 13 17]);
  477. hold on;
  478. cmap = flipud(roma(round(linspace(1, 256, length(ages))), :));
  479. colormap(cmap);
  480. for j = 1:length(ages)-1
  481. age_min = ages(j);
  482. age_max = ages(j) + window_size;
  483. idx = PMA >= age_min & PMA < age_max;
  484. if sum(idx) == 0 % if no profiles within age-range, skip
  485. continue;
  486. end
  487. avg_profile = mean(profiles(:, :, idx), [2, 3]);
  488. plot(avg_profile, -depth, 'Color', cmap(j, :), 'LineWidth', 1.5);
  489. end
  490. colorbar;
  491. clim([min_PMA max_PMA]);
  492. set(gca, 'YTick', []);
  493. set(gca, 'FontSize', 14);
  494. if i==1
  495. if mom == 1
  496. xlim([0.6 1.5]) % arbitrary limits for max cog
  497. else
  498. xlim([0.7 1.9]) % arbitrary limits for max variance
  499. end
  500. else
  501. if mom == 1
  502. xlim([0.6 1.8]) % arbitrary limits for min cog
  503. else
  504. xlim([0.8 1.7]) % arbitrary limits for min variance
  505. end
  506. end
  507. grid off;
  508. hold off;
  509. end
  510. % store the profiles of the parcels with the maximum/minimum
  511. % effects separately for each moment to use in the scatter plots
  512. if mom == 1
  513. max_cog_change_profs = max_change_profs;
  514. min_cog_change_profs = min_change_profs;
  515. else
  516. max_var_change_profs = max_change_profs;
  517. min_var_change_profs = min_change_profs;
  518. end
  519. end
  520. end
  521. for panel_B_scatter_plots = 1
  522. for mom = 1:length(moments)
  523. for i = 1:2
  524. if mom == 1 && i == 1
  525. profiles = max_cog_change_profs;
  526. elseif mom == 1
  527. profiles = min_cog_change_profs;
  528. elseif mom == 2 && i == 1
  529. profiles = max_var_change_profs;
  530. else
  531. profiles = min_var_change_profs;
  532. end
  533. % initialise array to store correlations at each depth
  534. depth_corrs = zeros(length(depths),1);
  535. % calculate correlation of intensities with PMA at each depth
  536. for depth = 1:length(depths)
  537. depth_corrs(depth) = corr(squeeze(mean(profiles(depth,:,:),2)), gen_table_avg_economo.PMA);
  538. end
  539. % plot depth-wise correlations as a scatter plot
  540. figure('units','centimeters','outerposition',[0 0 13 17]); hold on
  541. scatter(depth_corrs, depths, 90, 'filled', 'MarkerFaceColor', vik(80,:),...
  542. 'MarkerEdgeColor', 'k', 'LineWidth', 1.8);
  543. set(gca, 'YDir','reverse', 'YTick', [], 'YLim',[0 13], ...
  544. 'XLim', [0.18 0.75], 'TickLength',[0 0], 'FontSize', 14);
  545. grid off
  546. end
  547. end
  548. end
  549. end
  550. for figure_4 = 1
  551. for controlling_effects = 1
  552. moments = ["Centre of gravity", "Variance"];
  553. % run models which contain both GA and PNA as predictors (effects
  554. % controlling for the effects of the other)
  555. for mom = 1:length(moments)
  556. if mom == 1
  557. cog_sign_parcel_data = moment_age_model("cog", ["GA", "PNA"], ...
  558. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 1, 0);
  559. else
  560. var_sign_parcel_data = moment_age_model("variance", ["GA", "PNA"], ...
  561. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 1, 0);
  562. end
  563. end
  564. % calculate maximum absolute value for limits
  565. min_val = min([min(cog_sign_parcel_data(cog_sign_parcel_data > -100)); ...
  566. min(var_sign_parcel_data(var_sign_parcel_data > -100));]);
  567. max_val = max([max(cog_sign_parcel_data(cog_sign_parcel_data < 100)); ...
  568. max(var_sign_parcel_data(var_sign_parcel_data < 100))]);
  569. abs_lim = max([abs(min_val), abs(max_val)]);
  570. abs_lim = abs_lim + abs_lim/100;
  571. % plot the significant effects of GA and PNA on each moment
  572. for mom = 1:length(moments)
  573. if mom == 1
  574. sign_parcel_data_GA = cog_sign_parcel_data(:,1);
  575. sign_parcel_data_PNA = cog_sign_parcel_data(:,2);
  576. else
  577. sign_parcel_data_GA = var_sign_parcel_data(:,1);
  578. sign_parcel_data_PNA = var_sign_parcel_data(:,2);
  579. end
  580. sign_vert_data_PNA = BoSurfStatMakeParcelData(sign_parcel_data_PNA, wk40, wk40_economo_ind);
  581. figure; SurfStatViewData(sign_vert_data_PNA, wk40, strcat(moments(mom), ' sign. PNA'));
  582. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  583. SurfStatColLim([-abs_lim, abs_lim]);
  584. sign_vert_data_GA = BoSurfStatMakeParcelData(sign_parcel_data_GA, wk40, wk40_economo_ind);
  585. figure; SurfStatViewData(sign_vert_data_GA, wk40, strcat(moments(mom), ' sign. GA'));
  586. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  587. % SurfStatColLim([-abs_lim, abs_lim]);
  588. % in the manuscript, we use the same colourscale limits as the
  589. % figures of the independent models for the purpose of comparison.
  590. % If you want to use limits based only on this data, use the line above
  591. SurfStatColLim([-30.8513, 30.8513]); % limits of independent models
  592. end
  593. end
  594. for no_control = 1
  595. moments = ["Centre of gravity", "Variance"];
  596. % run individual models for GA and PNA as predictors (raw effects)
  597. for mom = 1:length(moments)
  598. if mom == 1
  599. cog_sign_parcel_data_GA = moment_age_model("cog", "GA", ...
  600. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 1, 0);
  601. cog_sign_parcel_data_PNA = moment_age_model("cog", "PNA", ...
  602. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 1, 0);
  603. else
  604. var_sign_parcel_data_GA = moment_age_model("variance", "GA", ...
  605. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 1, 0);
  606. var_sign_parcel_data_PNA = moment_age_model("variance", "PNA", ...
  607. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 1, 0);
  608. end
  609. end
  610. % calculate maximum absolute value for limits
  611. min_val = min([min(cog_sign_parcel_data_GA(cog_sign_parcel_data_GA > -100)); ...
  612. min(cog_sign_parcel_data_PNA(cog_sign_parcel_data_PNA > -100));
  613. min(var_sign_parcel_data_GA(var_sign_parcel_data_GA > -100)); ...
  614. min(var_sign_parcel_data_PNA(var_sign_parcel_data_PNA > -100))]);
  615. max_val = max([max(cog_sign_parcel_data_GA(cog_sign_parcel_data_GA < 100)); ...
  616. max(cog_sign_parcel_data_PNA(cog_sign_parcel_data_PNA < 100));
  617. max(var_sign_parcel_data_GA(var_sign_parcel_data_GA < 100)); ...
  618. max(var_sign_parcel_data_PNA(var_sign_parcel_data_PNA < 100))]);
  619. abs_lim = max([abs(min_val), abs(max_val)]);
  620. abs_lim = abs_lim + abs_lim/100;
  621. % plot the significant effects of GA and PNA on each moment
  622. for mom = 1:length(moments)
  623. if mom == 1
  624. sign_parcel_data_GA = cog_sign_parcel_data_GA;
  625. sign_parcel_data_PNA = cog_sign_parcel_data_PNA;
  626. else
  627. sign_parcel_data_GA = var_sign_parcel_data_GA;
  628. sign_parcel_data_PNA = var_sign_parcel_data_PNA;
  629. end
  630. sign_vert_data_PNA = BoSurfStatMakeParcelData(sign_parcel_data_PNA, wk40, wk40_economo_ind);
  631. figure; SurfStatViewData(sign_vert_data_PNA, wk40, strcat(moments(mom), ' sign. PNA'));
  632. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  633. SurfStatColLim([-abs_lim, abs_lim]);
  634. sign_vert_data_GA = BoSurfStatMakeParcelData(sign_parcel_data_GA, wk40, wk40_economo_ind);
  635. figure; SurfStatViewData(sign_vert_data_GA, wk40, strcat(moments(mom), ' sign. GA'));
  636. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  637. SurfStatColLim([-abs_lim, abs_lim]);
  638. end
  639. end
  640. end
  641. for figure_5 = 1
  642. for panel_A = 1
  643. % plotting first eigenmode
  644. eigenmode1 = eigenmodes(:,1);
  645. eigenmode1(eigenmode1~=0) = 1;
  646. figure; SurfStatViewData(eigenmode1, wk40);
  647. colormap([1 1 1; 0.1 0.01 0.56])
  648. % plotting vertex-wise eigenmodes 2-4
  649. for i = 1:size(eigenmodes, 2)
  650. figure; SurfStatViewData(eigenmodes(:,i), wk40);
  651. colormap(vik);
  652. end
  653. end
  654. for panel_B = 1
  655. % Note: the brain plots under the scatter plots are the same brain
  656. % plots generated in figures 3 and 4, but without applying significance
  657. % threshold on the t-maps and without a common colourscale. The code
  658. % to generate these is not repeated in this section
  659. n_perm = 10000; % number of permutations
  660. moments = ["Centre of gravity", "Variance"];
  661. % run linear models and concatenate t-values
  662. for mom = 1:length(moments)
  663. if mom == 1
  664. cog_parcel_data_PMA = moment_age_model("cog", "PMA", ...
  665. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 0);
  666. cog_parcel_data_GA_PNA = moment_age_model("cog", ["GA", "PNA"], ...
  667. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 0);
  668. else
  669. var_parcel_data_PMA = moment_age_model("variance", "PMA", ...
  670. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 0);
  671. var_parcel_data_GA_PNA = moment_age_model("variance", ["GA", "PNA"], ...
  672. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 0);
  673. end
  674. end
  675. t_maps = {cog_parcel_data_PMA, var_parcel_data_PMA, ...
  676. cog_parcel_data_GA_PNA(:,1), var_parcel_data_GA_PNA(:,1), ...
  677. cog_parcel_data_GA_PNA(:,2), var_parcel_data_GA_PNA(:,2)};
  678. for i = 1:numel(t_maps)
  679. t_maps{i}(t_maps{i} == -100) = NaN;
  680. end
  681. % spin the maps using the precomputed permutation indices
  682. spun_map = zeros(total_num_parcels_economo, n_perm, length(t_maps));
  683. for i = 1:length(t_maps)
  684. spun_map(:,:,i) = t_maps{i}(perm_id);
  685. end
  686. r_emp = zeros(length(t_maps), size(eigenmodes, 2));
  687. r_perm = zeros(n_perm, size(eigenmodes, 2), length(t_maps));
  688. spun_p = zeros(length(t_maps), size(eigenmodes, 2));
  689. null_prctiles = zeros(2, size(eigenmodes, 2), length(t_maps));
  690. for ii = 1:length(t_maps)
  691. spun_map = zeros(size(eigenmodes, 1), n_perm);
  692. % upsample parcel-wise effect maps to vertex-wise maps
  693. vert_t_map = BoSurfStatMakeParcelData(t_maps{ii}, wk40, wk40_economo_ind);
  694. for jj = 1:size(eigenmodes, 2)
  695. % correlate original effect map with eigenmode
  696. r_emp(ii, jj) = corr(vert_t_map', eigenmodes(:, jj), 'Rows', 'complete', 'Type', 'Pearson');
  697. % spin the parcel-wise effect map, upsample to vertex-wise
  698. % maps and correlate with eigenmode
  699. for kk = 1:n_perm
  700. spun_map(:,kk) = BoSurfStatMakeParcelData(t_maps{ii}(perm_id(:,kk)), ...
  701. wk40, wk40_economo_ind);
  702. r_perm(kk, jj, ii) = corr(spun_map(:, kk), eigenmodes(:, jj), ...
  703. 'Rows', 'complete', 'Type', 'Pearson');
  704. end
  705. % calculate two-tailed permutation p-value
  706. spun_p(ii, jj) = sum(abs(r_perm(:, jj, ii)) >= abs(r_emp(ii, jj))) / n_perm;
  707. % 95% null distribution interval (2.5th and 97.5th percentiles)
  708. null_prctiles(:, jj, ii) = prctile(r_perm(:, jj, ii), [2.5, 97.5]);
  709. end
  710. end
  711. % plot correlations with each eigenmode for each age-metric separately
  712. start_x = 30;
  713. side_gap = 15;
  714. gap_within = 5;
  715. gap_between = 20;
  716. % positions to plot values
  717. positions = [start_x, start_x+gap_within, start_x+2*gap_within, ...
  718. start_x+2*gap_within+gap_between, start_x+3*gap_within+gap_between, ...
  719. start_x+4*gap_within+gap_between];
  720. groupped_by = 'moments'; % choose between 'moments' or 'eigenmodes'
  721. orientation = 'vertical'; % choose between 'horizontal' or 'vertical'
  722. for age_idx = 1:3 % {for age = PMA, GA, PNA}
  723. figure;
  724. hold on;
  725. if strcmp(groupped_by, 'moments')
  726. correlation = r_emp(age_idx*2-1:age_idx*2, :);
  727. correlation = reshape(correlation', 1, []);
  728. whiskers = null_prctiles(:, :, age_idx*2-1:age_idx*2);
  729. whiskers = reshape(whiskers, 2, []);
  730. elseif strcmp(groupped_by, 'eigenmodes')
  731. correlation = reshape(correlation, 1, []);
  732. whiskers = permute(whiskers, [1, 3, 2]);
  733. whiskers = reshape(whiskers, 2, 6);
  734. end
  735. col_scaled = round(1 + ((correlation + max(abs(correlation))) ./ ...
  736. (2 * max(abs(correlation)))) * 255);
  737. if strcmp(orientation, 'horizontal')
  738. xline(0, 'k--', 'LineWidth', 1);
  739. scatter(correlation, -positions, 120, vik(col_scaled,:), 'filled');
  740. for i = 1:6
  741. plot([whiskers(1,i), whiskers(2,i)], [-positions(i), -positions(i)], ...
  742. 'Color', 'k', 'LineWidth', 1);
  743. end
  744. xlim([-(max(abs(correlation))+0.1), max(abs(correlation))+0.1]);
  745. ylim([-(max(positions)+side_gap), -(min(positions)-side_gap)]);
  746. set(gca, 'YTick', []);
  747. elseif strcmp(orientation, 'vertical')
  748. yline(0, 'k--', 'LineWidth', 1);
  749. scatter(positions, correlation, 120, vik(col_scaled,:), 'filled');
  750. for i = 1:6
  751. plot([positions(i), positions(i)], [whiskers(1,i), whiskers(2,i)], ...
  752. 'Color', 'k', 'LineWidth', 1);
  753. end
  754. ylim([-(max(abs(correlation))+0.1), max(abs(correlation))+0.1]);
  755. xlim([min(positions)-side_gap, max(positions)+side_gap]);
  756. set(gca, 'XTick', []);
  757. end
  758. set(gca, 'FontSize', 14);
  759. grid off;
  760. hold off;
  761. end
  762. end
  763. for panel_C = 1
  764. % upsample parcel-wise effects maps to vertex-wise maps
  765. vertex_maps = cell(1, numel(t_maps));
  766. for i = 1:numel(t_maps)
  767. vertex_maps{i} = BoSurfStatMakeParcelData(t_maps{i}, ...
  768. wk40, wk40_economo_ind);
  769. end
  770. % concatenate vertex-wise effect maps and eigenmodes in a single table
  771. vertex_matrix = cat(2, vertex_maps{:});
  772. vertex_matrix = reshape(vertex_matrix, [], numel(vertex_maps));
  773. vertex_matrix = [vertex_matrix, eigenmodes(:,1), eigenmodes(:,2), eigenmodes(:,3)];
  774. tmaps_emodes_vert = array2table(vertex_matrix, 'VariableNames', ...
  775. {'cog_PMA','var_PMA', 'cog_GA','var_GA', ...
  776. 'cog_PNA','var_PNA', 'EM1','EM2','EM3'});
  777. response_vars = ["cog_PMA","var_PMA","cog_GA","var_GA","cog_PNA","var_PNA"];
  778. regression_results = zeros(7,3,length(response_vars));
  779. % run linear models with each of the effect maps as response
  780. % variables and all 7 different combinations of eigenmodes as predictors
  781. for var = 1:length(response_vars)
  782. mdl_EM1 = fitlm(tmaps_emodes_vert, strcat(response_vars(var), ' ~ EM1'));
  783. regression_results(1,1,var) = mdl_EM1.Rsquared.Adjusted;
  784. mdl_EM2 = fitlm(tmaps_emodes_vert, strcat(response_vars(var), ' ~ EM2'));
  785. regression_results(2,1,var) = mdl_EM2.Rsquared.Adjusted;
  786. mdl_EM3 = fitlm(tmaps_emodes_vert, strcat(response_vars(var), ' ~ EM3'));
  787. regression_results(3,1,var) = mdl_EM3.Rsquared.Adjusted;
  788. mdl_EM1_2 = fitlm(tmaps_emodes_vert, strcat(response_vars(var), ' ~ EM1 + EM2'));
  789. regression_results(4,1,var) = mdl_EM1_2.Rsquared.Adjusted;
  790. mdl_EM1_3 = fitlm(tmaps_emodes_vert, strcat(response_vars(var), ' ~ EM1 + EM3'));
  791. regression_results(5,1,var) = mdl_EM1_3.Rsquared.Adjusted;
  792. mdl_EM2_3 = fitlm(tmaps_emodes_vert, strcat(response_vars(var), ' ~ EM2 + EM3'));
  793. regression_results(6,1,var) = mdl_EM2_3.Rsquared.Adjusted;
  794. mdl_EM1_2_3 = fitlm(tmaps_emodes_vert, strcat(response_vars(var), ' ~ EM1 + EM2 + EM3'));
  795. regression_results(7,1,var) = mdl_EM1_2_3.Rsquared.Adjusted;
  796. end
  797. r_sqrd_vals = squeeze(regression_results(:,1,:))';
  798. tmap_names = ["cog-PMA","var-PMA","cog-GA","var-GA","cog-PNA","var-PNA"];
  799. model_names = ["EM2","EM3","EM4","EM2+EM3","EM2+EM4","EM3+EM4","EM2+EM3+EM4"];
  800. % plot the adjusted R-square values of each model in a bar plot
  801. cols = [vik(145,:); vik(195,:)];
  802. gap_between = 1;
  803. block_width = size(r_sqrd_vals,2) + gap_between;
  804. for age = 1:3
  805. figure('units','centimeters','outerposition',[0 0 20 12]); hold on;
  806. data_to_plot = r_sqrd_vals((age*2-1):age*2,:);
  807. for mom = 1:2
  808. x_pos = (mom-1)*block_width + (1:size(r_sqrd_vals,2));
  809. bar(x_pos,data_to_plot(mom,:), 0.8, 'FaceColor', cols(mom,:), ...
  810. 'EdgeColor', 'k', 'LineWidth', 1);
  811. end
  812. set(gca, 'FontSize', 14);
  813. ylim([0 max(r_sqrd_vals(:))*1.1]);
  814. box on; grid off
  815. end
  816. end
  817. end
  818. for supp_figure_1 = 1
  819. moments = ["Centre of gravity", "Variance"];
  820. % initialise table to store the correlations between the effect maps of
  821. % the original dataset and the dataset excluding twins
  822. r_emp = table(zeros(numel(moments),1), zeros(numel(moments),1), ...
  823. 'RowNames', moments, 'VariableNames', ["Correlation", "p_value"]);
  824. for mom = 1:length(moments)
  825. if mom == 1
  826. cog_parcel_data_PMA = moment_age_model("cog", "PMA", ...
  827. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 0);
  828. cog_parcel_data_PMA_no_twins = moment_age_model("cog", "PMA", ...
  829. gen_table_no_twins, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 0);
  830. else
  831. var_parcel_data_PMA = moment_age_model("variance", "PMA", ...
  832. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 0);
  833. var_parcel_data_PMA_no_twins = moment_age_model("variance", "PMA", ...
  834. gen_table_no_twins, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 0);
  835. end
  836. end
  837. % calculate maximum absolute value for limits
  838. min_val = min([min(cog_parcel_data_PMA(cog_parcel_data_PMA > -100)); ...
  839. min(cog_parcel_data_PMA_no_twins(cog_parcel_data_PMA_no_twins > -100));
  840. min(var_parcel_data_PMA(var_parcel_data_PMA > -100)); ...
  841. min(var_parcel_data_PMA_no_twins(var_parcel_data_PMA_no_twins > -100))]);
  842. max_val = max([max(cog_parcel_data_PMA(cog_parcel_data_PMA < 100)); ...
  843. max(cog_parcel_data_PMA_no_twins(cog_parcel_data_PMA_no_twins < 100)); ...
  844. max(var_parcel_data_PMA(var_parcel_data_PMA < 100)); ...
  845. max(var_parcel_data_PMA_no_twins(var_parcel_data_PMA_no_twins < 100))]);
  846. abs_lim = max(abs(min_val), abs(max_val));
  847. abs_lim = abs_lim + abs_lim/100;
  848. % plot the significant effects of PMA on each moment
  849. for mom = 1:length(moments)
  850. if mom == 1
  851. parc_data_PMA = cog_parcel_data_PMA;
  852. parc_data_PMA_no_twins = cog_parcel_data_PMA_no_twins;
  853. else
  854. parc_data_PMA = var_parcel_data_PMA;
  855. parc_data_PMA_no_twins = var_parcel_data_PMA_no_twins;
  856. end
  857. vert_data_PMA = BoSurfStatMakeParcelData(parc_data_PMA, wk40, wk40_economo_ind);
  858. figure; SurfStatViewData(vert_data_PMA, wk40, strcat(moments(mom), ' PMA'));
  859. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  860. SurfStatColLim([-abs_lim, abs_lim]);
  861. vert_data_PMA_no_twins = BoSurfStatMakeParcelData(parc_data_PMA_no_twins, wk40, wk40_economo_ind);
  862. figure; SurfStatViewData(vert_data_PMA_no_twins, wk40, strcat(moments(mom), ' PMA - no twins'));
  863. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  864. SurfStatColLim([-abs_lim, abs_lim]);
  865. % replace -100 values with NaNs for the correlation
  866. parc_data_PMA(parc_data_PMA==-100)=NaN;
  867. parc_data_PMA_no_twins(parc_data_PMA_no_twins==-100)=NaN;
  868. spun_map = parc_data_PMA(perm_id); % spin one of the maps of effects
  869. r_emp.Correlation(mom)=corr(parc_data_PMA, parc_data_PMA_no_twins, ...
  870. 'Rows', 'complete', 'Type', 'Pearson'); % correlate the effects
  871. % run permutation test
  872. r_perm = zeros(n_perm,1);
  873. for kk=1:n_perm
  874. r_perm(kk) = corr(spun_map(:, kk), parc_data_PMA_no_twins, ...
  875. 'Rows', 'complete', 'Type', 'Pearson');
  876. end
  877. r_emp.p_value(mom) = sum(abs(r_perm(:)) >= abs(r_emp.Correlation(mom))) / n_perm; % p-value after spin test
  878. end
  879. end
  880. for supp_figures_2_3 = 1
  881. moments = ["Centre of gravity", "Variance"];
  882. % initialise tables to store the correlations between the effect maps of
  883. % the original dataset and the dataset excluding twins
  884. r_emp_GA = table(zeros(numel(moments),1), zeros(numel(moments),1), ...
  885. 'RowNames', moments, 'VariableNames', ["Correlation", "p_value"]);
  886. r_emp_PNA = table(zeros(numel(moments),1), zeros(numel(moments),1), ...
  887. 'RowNames', moments, 'VariableNames', ["Correlation", "p_value"]);
  888. % run models which contain both GA and PNA as predictors (effects
  889. % controlling for the effects of the other)
  890. for mom = 1:length(moments)
  891. if mom == 1
  892. cog_parcel_data = moment_age_model("cog", ["GA", "PNA"], ...
  893. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 0);
  894. cog_parcel_data_no_twins = moment_age_model("cog", ["GA", "PNA"], ...
  895. gen_table_no_twins, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 0);
  896. else
  897. var_parcel_data = moment_age_model("variance", ["GA", "PNA"], ...
  898. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 0);
  899. var_parcel_data_no_twins = moment_age_model("variance", ["GA", "PNA"], ...
  900. gen_table_no_twins, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 0);
  901. end
  902. end
  903. % calculate maximum absolute value for limits for each age-metric separately
  904. min_val_GA = min([min(cog_parcel_data(cog_parcel_data(:,1) > -100, 1)); ...
  905. min(cog_parcel_data_no_twins(cog_parcel_data_no_twins(:,1) > -100, 1)); ...
  906. min(var_parcel_data(var_parcel_data(:,1) > -100, 1)); ...
  907. min(var_parcel_data_no_twins(var_parcel_data_no_twins(:,1) > -100, 1))]);
  908. max_val_GA = max([max(cog_parcel_data(cog_parcel_data(:,1) < 100, 1)); ...
  909. max(cog_parcel_data_no_twins(cog_parcel_data_no_twins(:,1) < 100, 1)); ...
  910. max(var_parcel_data(var_parcel_data(:,1) < 100, 1)); ...
  911. max(var_parcel_data_no_twins(var_parcel_data_no_twins(:,1) < 100, 1))]);
  912. abs_lim_GA = max([abs(min_val_GA), abs(max_val_GA)]);
  913. abs_lim_GA = abs_lim_GA + abs_lim_GA/100;
  914. min_val_PNA = min([min(cog_parcel_data(cog_parcel_data(:,2) > -100, 2)); ...
  915. min(cog_parcel_data_no_twins(cog_parcel_data_no_twins(:,2) > -100, 2)); ...
  916. min(var_parcel_data(var_parcel_data(:,2) > -100, 2)); ...
  917. min(var_parcel_data_no_twins(var_parcel_data_no_twins(:,2) > -100, 2))]);
  918. max_val_PNA = max([max(cog_parcel_data(cog_parcel_data(:,2) < 100, 2)); ...
  919. max(cog_parcel_data_no_twins(cog_parcel_data_no_twins(:,2) < 100, 2)); ...
  920. max(var_parcel_data(var_parcel_data(:,2) < 100, 2)); ...
  921. max(var_parcel_data_no_twins(var_parcel_data_no_twins(:,2) < 100, 2))]);
  922. abs_lim_PNA = max([abs(min_val_PNA), abs(max_val_PNA)]);
  923. abs_lim_PNA = abs_lim_PNA + abs_lim_PNA/100;
  924. % plot the significant effects of GA and PNA on each moment
  925. for mom = 1:length(moments)
  926. if mom == 1
  927. parcel_data_GA = cog_parcel_data(:,1);
  928. parcel_data_GA_no_twins = cog_parcel_data_no_twins(:,1);
  929. parcel_data_PNA = cog_parcel_data(:,2);
  930. parcel_data_PNA_no_twins = cog_parcel_data_no_twins(:,2);
  931. else
  932. parcel_data_GA = var_parcel_data(:,1);
  933. parcel_data_GA_no_twins = var_parcel_data_no_twins(:,1);
  934. parcel_data_PNA = var_parcel_data(:,2);
  935. parcel_data_PNA_no_twins = var_parcel_data_no_twins(:,2);
  936. end
  937. vert_data_PNA = BoSurfStatMakeParcelData(parcel_data_PNA, wk40, wk40_economo_ind);
  938. figure; SurfStatViewData(vert_data_PNA, wk40, strcat(moments(mom), ' PNA'));
  939. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  940. SurfStatColLim([-abs_lim_PNA, abs_lim_PNA]);
  941. vert_data_PNA_no_twins = BoSurfStatMakeParcelData(parcel_data_PNA_no_twins, wk40, wk40_economo_ind);
  942. figure; SurfStatViewData(vert_data_PNA_no_twins, wk40, strcat(moments(mom), ' PNA - no twins'));
  943. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  944. SurfStatColLim([-abs_lim_PNA, abs_lim_PNA]);
  945. vert_data_GA = BoSurfStatMakeParcelData(parcel_data_GA, wk40, wk40_economo_ind);
  946. figure; SurfStatViewData(vert_data_GA, wk40, strcat(moments(mom), ' GA'));
  947. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  948. SurfStatColLim([-abs_lim_GA, abs_lim_GA]);
  949. vert_data_GA_no_twins = BoSurfStatMakeParcelData(parcel_data_GA_no_twins, wk40, wk40_economo_ind);
  950. figure; SurfStatViewData(vert_data_GA_no_twins, wk40, strcat(moments(mom), ' GA - no twins'));
  951. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  952. SurfStatColLim([-abs_lim_GA, abs_lim_GA]);
  953. % replace -100 values with NaNs for the correlation
  954. parcel_data_GA(parcel_data_GA==-100)=NaN;
  955. parcel_data_GA_no_twins(parcel_data_GA_no_twins==-100)=NaN;
  956. parcel_data_PNA(parcel_data_PNA==-100)=NaN;
  957. parcel_data_PNA_no_twins(parcel_data_PNA_no_twins==-100)=NaN;
  958. spun_map_GA = parcel_data_GA(perm_id); % spin one of the GA maps of effects
  959. spun_map_PNA = parcel_data_PNA(perm_id); % spin one of the PNA maps of effects
  960. r_emp_GA.Correlation(mom)=corr(parcel_data_GA, parcel_data_GA_no_twins, ...
  961. 'Rows', 'complete', 'Type', 'Pearson'); % correlate the GA effects
  962. r_emp_PNA.Correlation(mom)=corr(parcel_data_PNA, parcel_data_PNA_no_twins, ...
  963. 'Rows', 'complete', 'Type', 'Pearson'); % correlate the PNA effects
  964. % run permutation test
  965. r_perm_GA = zeros(n_perm,1);
  966. r_perm_PNA = zeros(n_perm,1);
  967. for kk=1:n_perm
  968. r_perm_GA(kk) = corr(spun_map_GA(:, kk), parcel_data_GA_no_twins, ...
  969. 'Rows', 'complete', 'Type', 'Pearson');
  970. r_perm_PNA(kk) = corr(spun_map_PNA(:, kk), parcel_data_PNA_no_twins, ...
  971. 'Rows', 'complete', 'Type', 'Pearson');
  972. end
  973. r_emp_GA.p_value(mom) = sum(abs(r_perm_GA(:)) ...
  974. >= abs(r_emp_GA.Correlation(mom))) / n_perm; % p-value after spin test
  975. r_emp_PNA.p_value(mom) = sum(abs(r_perm_PNA(:)) ...
  976. >= abs(r_emp_PNA.Correlation(mom))) / n_perm; % p-value after spin test
  977. end
  978. end
  979. for supp_figure_4 = 1
  980. moments = ["Centre of gravity", "Variance"];
  981. % initialise table to store the correlations between the effect maps of the
  982. % original dataset and the dataset excluding extremely preterm (EPT) infants
  983. r_emp_PMA = table(zeros(numel(moments),1), zeros(numel(moments),1), ...
  984. 'RowNames', moments, 'VariableNames', ["Correlation", "p_value"]);
  985. r_emp_GA = table(zeros(numel(moments),1), zeros(numel(moments),1), ...
  986. 'RowNames', moments, 'VariableNames', ["Correlation", "p_value"]);
  987. r_emp_PNA = table(zeros(numel(moments),1), zeros(numel(moments),1), ...
  988. 'RowNames', moments, 'VariableNames', ["Correlation", "p_value"]);
  989. for mom = 1:length(moments)
  990. if mom == 1
  991. cog_parcel_data_PMA = moment_age_model("cog", "PMA", ...
  992. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 0);
  993. cog_parcel_data_PMA_no_EPT = moment_age_model("cog", "PMA", ...
  994. gen_table_economo(gen_table_economo.GA >= 28, :), uparc_economo, ...
  995. total_num_parcels_economo, valid_parcels_economo, 0, 0);
  996. cog_parcel_data_GA_PNA = moment_age_model("cog", ["GA", "PNA"], ...
  997. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 0);
  998. cog_parcel_data_GA_PNA_no_EPT = moment_age_model("cog", ["GA", "PNA"], ...
  999. gen_table_economo(gen_table_economo.GA >= 28, :), uparc_economo, ...
  1000. total_num_parcels_economo, valid_parcels_economo, 0, 0);
  1001. else
  1002. var_parcel_data_PMA = moment_age_model("variance", "PMA", ...
  1003. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 0);
  1004. var_parcel_data_PMA_no_EPT = moment_age_model("variance", "PMA", ...
  1005. gen_table_economo(gen_table_economo.GA >= 28, :), uparc_economo, ...
  1006. total_num_parcels_economo, valid_parcels_economo, 0, 0);
  1007. var_parcel_data_GA_PNA = moment_age_model("variance", ["GA", "PNA"], ...
  1008. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 0);
  1009. var_parcel_data_GA_PNA_no_EPT = moment_age_model("variance", ["GA", "PNA"], ...
  1010. gen_table_economo(gen_table_economo.GA >= 28, :), uparc_economo, ...
  1011. total_num_parcels_economo, valid_parcels_economo, 0, 0);
  1012. end
  1013. end
  1014. % calculate maximum absolute value for limits
  1015. min_val = min([min(cog_parcel_data_PMA(cog_parcel_data_PMA > -100)); ...
  1016. min(cog_parcel_data_PMA_no_EPT(cog_parcel_data_PMA_no_EPT > -100)); ...
  1017. min(cog_parcel_data_GA_PNA(cog_parcel_data_GA_PNA > -100)); ...
  1018. min(cog_parcel_data_GA_PNA_no_EPT(cog_parcel_data_GA_PNA_no_EPT > -100)); ...
  1019. min(var_parcel_data_PMA(var_parcel_data_PMA > -100)); ...
  1020. min(var_parcel_data_PMA_no_EPT(var_parcel_data_PMA_no_EPT > -100)); ...
  1021. min(var_parcel_data_GA_PNA(var_parcel_data_GA_PNA > -100)); ...
  1022. min(var_parcel_data_GA_PNA_no_EPT(var_parcel_data_GA_PNA_no_EPT > -100))]);
  1023. max_val = max([max(cog_parcel_data_PMA(cog_parcel_data_PMA < 100)); ...
  1024. max(cog_parcel_data_PMA_no_EPT(cog_parcel_data_PMA_no_EPT < 100)); ...
  1025. max(cog_parcel_data_GA_PNA(cog_parcel_data_GA_PNA < 100)); ...
  1026. max(cog_parcel_data_GA_PNA_no_EPT(cog_parcel_data_GA_PNA_no_EPT < 100)); ...
  1027. max(var_parcel_data_PMA(var_parcel_data_PMA < 100)); ...
  1028. max(var_parcel_data_PMA_no_EPT(var_parcel_data_PMA_no_EPT < 100)); ...
  1029. max(var_parcel_data_GA_PNA(var_parcel_data_GA_PNA < 100)); ...
  1030. max(var_parcel_data_GA_PNA_no_EPT(var_parcel_data_GA_PNA_no_EPT < 100))]);
  1031. abs_lim = max(abs(min_val), abs(max_val));
  1032. abs_lim = abs_lim + abs_lim/100;
  1033. % plot the significant effects of PMA on each moment
  1034. for mom = 1:length(moments)
  1035. if mom == 1
  1036. parcel_data_PMA = cog_parcel_data_PMA;
  1037. parcel_data_PMA_no_EPT = cog_parcel_data_PMA_no_EPT;
  1038. parcel_data_GA = cog_parcel_data_GA_PNA(:,1);
  1039. parcel_data_GA_no_EPT = cog_parcel_data_GA_PNA_no_EPT(:,1);
  1040. parcel_data_PNA = cog_parcel_data_GA_PNA(:,2);
  1041. parcel_data_PNA_no_EPT = cog_parcel_data_GA_PNA_no_EPT(:,2);
  1042. else
  1043. parcel_data_PMA = var_parcel_data_PMA;
  1044. parcel_data_PMA_no_EPT = var_parcel_data_PMA_no_EPT;
  1045. parcel_data_GA = var_parcel_data_GA_PNA(:,1);
  1046. parcel_data_GA_no_EPT = var_parcel_data_GA_PNA_no_EPT(:,1);
  1047. parcel_data_PNA = var_parcel_data_GA_PNA(:,2);
  1048. parcel_data_PNA_no_EPT = var_parcel_data_GA_PNA_no_EPT(:,2);
  1049. end
  1050. vert_data_PMA = BoSurfStatMakeParcelData(parcel_data_PMA, wk40, wk40_economo_ind);
  1051. figure; SurfStatViewData(vert_data_PMA, wk40, strcat(moments(mom), ' PMA'));
  1052. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  1053. SurfStatColLim([-abs_lim, abs_lim]);
  1054. vert_data_PMA_no_EPT = BoSurfStatMakeParcelData(parcel_data_PMA_no_EPT, wk40, wk40_economo_ind);
  1055. figure; SurfStatViewData(vert_data_PMA_no_EPT, wk40, strcat(moments(mom), ' PMA - no EPT'));
  1056. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  1057. SurfStatColLim([-abs_lim, abs_lim]);
  1058. vert_data_GA = BoSurfStatMakeParcelData(parcel_data_GA, wk40, wk40_economo_ind);
  1059. figure; SurfStatViewData(vert_data_GA, wk40, strcat(moments(mom), ' GA'));
  1060. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  1061. SurfStatColLim([-abs_lim, abs_lim]);
  1062. vert_data_GA_no_EPT = BoSurfStatMakeParcelData(parcel_data_GA_no_EPT, wk40, wk40_economo_ind);
  1063. figure; SurfStatViewData(vert_data_GA_no_EPT, wk40, strcat(moments(mom), ' GA - no EPT'));
  1064. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  1065. SurfStatColLim([-abs_lim, abs_lim]);
  1066. vert_data_PNA = BoSurfStatMakeParcelData(parcel_data_PNA, wk40, wk40_economo_ind);
  1067. figure; SurfStatViewData(vert_data_PNA, wk40, strcat(moments(mom), ' PNA'));
  1068. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  1069. SurfStatColLim([-abs_lim, abs_lim]);
  1070. vert_data_PNA_no_EPT = BoSurfStatMakeParcelData(parcel_data_PNA_no_EPT, wk40, wk40_economo_ind);
  1071. figure; SurfStatViewData(vert_data_PNA_no_EPT, wk40, strcat(moments(mom), ' PNA - no EPT'));
  1072. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  1073. SurfStatColLim([-abs_lim, abs_lim]);
  1074. % replace -100 values with NaNs for the correlation
  1075. parcel_data_PMA(parcel_data_PMA==-100)=NaN;
  1076. parcel_data_PMA_no_EPT(parcel_data_PMA_no_EPT==-100)=NaN;
  1077. parcel_data_GA(parcel_data_GA==-100)=NaN;
  1078. parcel_data_GA_no_EPT(parcel_data_GA_no_EPT==-100)=NaN;
  1079. parcel_data_PNA(parcel_data_PNA==-100)=NaN;
  1080. parcel_data_PNA_no_EPT(parcel_data_PNA_no_EPT==-100)=NaN;
  1081. spun_map_PMA = parcel_data_PMA(perm_id); % spin one of the PMA maps of effects
  1082. spun_map_GA = parcel_data_GA(perm_id); % spin one of the GA maps of effects
  1083. spun_map_PNA = parcel_data_PNA(perm_id); % spin one of the PNA maps of effects
  1084. r_emp_PMA.Correlation(mom)=corr(parcel_data_PMA, parcel_data_PMA_no_EPT, ...
  1085. 'Rows', 'complete', 'Type', 'Pearson'); % correlate the PMA effects
  1086. r_emp_GA.Correlation(mom)=corr(parcel_data_GA, parcel_data_GA_no_EPT, ...
  1087. 'Rows', 'complete', 'Type', 'Pearson'); % correlate the GA effects
  1088. r_emp_PNA.Correlation(mom)=corr(parcel_data_PNA, parcel_data_PNA_no_EPT, ...
  1089. 'Rows', 'complete', 'Type', 'Pearson'); % correlate the PNA effects
  1090. % run permutation test
  1091. r_perm_PMA = zeros(n_perm,1);
  1092. r_perm_GA = zeros(n_perm,1);
  1093. r_perm_PNA = zeros(n_perm,1);
  1094. for kk=1:n_perm
  1095. r_perm_PMA(kk) = corr(spun_map_PMA(:, kk), parcel_data_PMA_no_EPT, ...
  1096. 'Rows', 'complete', 'Type', 'Pearson');
  1097. r_perm_GA(kk) = corr(spun_map_GA(:, kk), parcel_data_GA_no_EPT, ...
  1098. 'Rows', 'complete', 'Type', 'Pearson');
  1099. r_perm_PNA(kk) = corr(spun_map_PNA(:, kk), parcel_data_PNA_no_EPT, ...
  1100. 'Rows', 'complete', 'Type', 'Pearson');
  1101. end
  1102. r_emp_PMA.p_value(mom) = sum(abs(r_perm(:)) ...
  1103. >= abs(r_emp_PMA.Correlation(mom))) / n_perm; % p-value after spin test
  1104. r_emp_GA.p_value(mom) = sum(abs(r_perm(:)) ...
  1105. >= abs(r_emp_GA.Correlation(mom))) / n_perm; % p-value after spin test
  1106. r_emp_PNA.p_value(mom) = sum(abs(r_perm(:)) ...
  1107. >= abs(r_emp_PNA.Correlation(mom))) / n_perm; % p-value after spin test
  1108. end
  1109. end
  1110. for supp_figure_5 = 1
  1111. moments = ["Centre of gravity", "Variance"];
  1112. % initialise table to store the correlations between the effect maps of the
  1113. % original dataset and the dataset excluding very preterm (VPT) infants
  1114. r_emp_PMA = table(zeros(numel(moments),1), zeros(numel(moments),1), ...
  1115. 'RowNames', moments, 'VariableNames', ["Correlation", "p_value"]);
  1116. r_emp_GA = table(zeros(numel(moments),1), zeros(numel(moments),1), ...
  1117. 'RowNames', moments, 'VariableNames', ["Correlation", "p_value"]);
  1118. r_emp_PNA = table(zeros(numel(moments),1), zeros(numel(moments),1), ...
  1119. 'RowNames', moments, 'VariableNames', ["Correlation", "p_value"]);
  1120. for mom = 1:length(moments)
  1121. if mom == 1
  1122. cog_parcel_data_PMA = moment_age_model("cog", "PMA", ...
  1123. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 0);
  1124. cog_parcel_data_PMA_no_VPT = moment_age_model("cog", "PMA", ...
  1125. gen_table_economo(gen_table_economo.GA >= 32, :), uparc_economo, ...
  1126. total_num_parcels_economo, valid_parcels_economo, 0, 0);
  1127. cog_parcel_data_GA_PNA = moment_age_model("cog", ["GA", "PNA"], ...
  1128. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 0);
  1129. cog_parcel_data_GA_PNA_no_VPT = moment_age_model("cog", ["GA", "PNA"], ...
  1130. gen_table_economo(gen_table_economo.GA >= 32, :), uparc_economo, ...
  1131. total_num_parcels_economo, valid_parcels_economo, 0, 0);
  1132. else
  1133. var_parcel_data_PMA = moment_age_model("variance", "PMA", ...
  1134. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 0);
  1135. var_parcel_data_PMA_no_VPT = moment_age_model("variance", "PMA", ...
  1136. gen_table_economo(gen_table_economo.GA >= 32, :), uparc_economo, ...
  1137. total_num_parcels_economo, valid_parcels_economo, 0, 0);
  1138. var_parcel_data_GA_PNA = moment_age_model("variance", ["GA", "PNA"], ...
  1139. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 0);
  1140. var_parcel_data_GA_PNA_no_VPT = moment_age_model("variance", ["GA", "PNA"], ...
  1141. gen_table_economo(gen_table_economo.GA >= 32, :), uparc_economo, ...
  1142. total_num_parcels_economo, valid_parcels_economo, 0, 0);
  1143. end
  1144. end
  1145. % calculate maximum absolute value for limits
  1146. min_val = min([min(cog_parcel_data_PMA(cog_parcel_data_PMA > -100)); ...
  1147. min(cog_parcel_data_PMA_no_VPT(cog_parcel_data_PMA_no_VPT > -100)); ...
  1148. min(cog_parcel_data_GA_PNA(cog_parcel_data_GA_PNA > -100)); ...
  1149. min(cog_parcel_data_GA_PNA_no_VPT(cog_parcel_data_GA_PNA_no_VPT > -100)); ...
  1150. min(var_parcel_data_PMA(var_parcel_data_PMA > -100)); ...
  1151. min(var_parcel_data_PMA_no_VPT(var_parcel_data_PMA_no_VPT > -100)); ...
  1152. min(var_parcel_data_GA_PNA(var_parcel_data_GA_PNA > -100)); ...
  1153. min(var_parcel_data_GA_PNA_no_VPT(var_parcel_data_GA_PNA_no_VPT > -100))]);
  1154. max_val = max([max(cog_parcel_data_PMA(cog_parcel_data_PMA < 100)); ...
  1155. max(cog_parcel_data_PMA_no_VPT(cog_parcel_data_PMA_no_VPT < 100)); ...
  1156. max(cog_parcel_data_GA_PNA(cog_parcel_data_GA_PNA < 100)); ...
  1157. max(cog_parcel_data_GA_PNA_no_VPT(cog_parcel_data_GA_PNA_no_VPT < 100)); ...
  1158. max(var_parcel_data_PMA(var_parcel_data_PMA < 100)); ...
  1159. max(var_parcel_data_PMA_no_VPT(var_parcel_data_PMA_no_VPT < 100)); ...
  1160. max(var_parcel_data_GA_PNA(var_parcel_data_GA_PNA < 100)); ...
  1161. max(var_parcel_data_GA_PNA_no_VPT(var_parcel_data_GA_PNA_no_VPT < 100))]);
  1162. abs_lim = max(abs(min_val), abs(max_val));
  1163. abs_lim = abs_lim + abs_lim/100;
  1164. % plot the significant effects of PMA on each moment
  1165. for mom = 1:length(moments)
  1166. if mom == 1
  1167. parcel_data_PMA = cog_parcel_data_PMA;
  1168. parcel_data_PMA_no_VPT = cog_parcel_data_PMA_no_VPT;
  1169. parcel_data_GA = cog_parcel_data_GA_PNA(:,1);
  1170. parcel_data_GA_no_VPT = cog_parcel_data_GA_PNA_no_VPT(:,1);
  1171. parcel_data_PNA = cog_parcel_data_GA_PNA(:,2);
  1172. parcel_data_PNA_no_VPT = cog_parcel_data_GA_PNA_no_VPT(:,2);
  1173. else
  1174. parcel_data_PMA = var_parcel_data_PMA;
  1175. parcel_data_PMA_no_VPT = var_parcel_data_PMA_no_VPT;
  1176. parcel_data_GA = var_parcel_data_GA_PNA(:,1);
  1177. parcel_data_GA_no_VPT = var_parcel_data_GA_PNA_no_VPT(:,1);
  1178. parcel_data_PNA = var_parcel_data_GA_PNA(:,2);
  1179. parcel_data_PNA_no_VPT = var_parcel_data_GA_PNA_no_VPT(:,2);
  1180. end
  1181. vert_data_PMA = BoSurfStatMakeParcelData(parcel_data_PMA, wk40, wk40_economo_ind);
  1182. figure; SurfStatViewData(vert_data_PMA, wk40, strcat(moments(mom), ' PMA'));
  1183. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  1184. SurfStatColLim([-abs_lim, abs_lim]);
  1185. vert_data_PMA_no_VPT = BoSurfStatMakeParcelData(parcel_data_PMA_no_VPT, wk40, wk40_economo_ind);
  1186. figure; SurfStatViewData(vert_data_PMA_no_VPT, wk40, strcat(moments(mom), ' PMA - no VPT'));
  1187. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  1188. SurfStatColLim([-abs_lim, abs_lim]);
  1189. vert_data_GA = BoSurfStatMakeParcelData(parcel_data_GA, wk40, wk40_economo_ind);
  1190. figure; SurfStatViewData(vert_data_GA, wk40, strcat(moments(mom), ' GA'));
  1191. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  1192. SurfStatColLim([-abs_lim, abs_lim]);
  1193. vert_data_GA_no_VPT = BoSurfStatMakeParcelData(parcel_data_GA_no_VPT, wk40, wk40_economo_ind);
  1194. figure; SurfStatViewData(vert_data_GA_no_VPT, wk40, strcat(moments(mom), ' GA - no VPT'));
  1195. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  1196. SurfStatColLim([-abs_lim, abs_lim]);
  1197. vert_data_PNA = BoSurfStatMakeParcelData(parcel_data_PNA, wk40, wk40_economo_ind);
  1198. figure; SurfStatViewData(vert_data_PNA, wk40, strcat(moments(mom), ' PNA'));
  1199. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  1200. SurfStatColLim([-abs_lim, abs_lim]);
  1201. vert_data_PNA_no_VPT = BoSurfStatMakeParcelData(parcel_data_PNA_no_VPT, wk40, wk40_economo_ind);
  1202. figure; SurfStatViewData(vert_data_PNA_no_VPT, wk40, strcat(moments(mom), ' PNA - no VPT'));
  1203. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  1204. SurfStatColLim([-abs_lim, abs_lim]);
  1205. % replace -100 values with NaNs for the correlation
  1206. parcel_data_PMA(parcel_data_PMA==-100)=NaN;
  1207. parcel_data_PMA_no_VPT(parcel_data_PMA_no_VPT==-100)=NaN;
  1208. parcel_data_GA(parcel_data_GA==-100)=NaN;
  1209. parcel_data_GA_no_VPT(parcel_data_GA_no_VPT==-100)=NaN;
  1210. parcel_data_PNA(parcel_data_PNA==-100)=NaN;
  1211. parcel_data_PNA_no_VPT(parcel_data_PNA_no_VPT==-100)=NaN;
  1212. spun_map_PMA = parcel_data_PMA(perm_id); % spin one of the PMA maps of effects
  1213. spun_map_GA = parcel_data_GA(perm_id); % spin one of the GA maps of effects
  1214. spun_map_PNA = parcel_data_PNA(perm_id); % spin one of the PNA maps of effects
  1215. r_emp_PMA.Correlation(mom)=corr(parcel_data_PMA, parcel_data_PMA_no_VPT, ...
  1216. 'Rows', 'complete', 'Type', 'Pearson'); % correlate the PMA effects
  1217. r_emp_GA.Correlation(mom)=corr(parcel_data_GA, parcel_data_GA_no_VPT, ...
  1218. 'Rows', 'complete', 'Type', 'Pearson'); % correlate the GA effects
  1219. r_emp_PNA.Correlation(mom)=corr(parcel_data_PNA, parcel_data_PNA_no_VPT, ...
  1220. 'Rows', 'complete', 'Type', 'Pearson'); % correlate the PNA effects
  1221. % run permutation test
  1222. r_perm_PMA = zeros(n_perm,1);
  1223. r_perm_GA = zeros(n_perm,1);
  1224. r_perm_PNA = zeros(n_perm,1);
  1225. for kk=1:n_perm
  1226. r_perm_PMA(kk) = corr(spun_map_PMA(:, kk), parcel_data_PMA_no_VPT, ...
  1227. 'Rows', 'complete', 'Type', 'Pearson');
  1228. r_perm_GA(kk) = corr(spun_map_GA(:, kk), parcel_data_GA_no_VPT, ...
  1229. 'Rows', 'complete', 'Type', 'Pearson');
  1230. r_perm_PNA(kk) = corr(spun_map_PNA(:, kk), parcel_data_PNA_no_VPT, ...
  1231. 'Rows', 'complete', 'Type', 'Pearson');
  1232. end
  1233. r_emp_PMA.p_value(mom) = sum(abs(r_perm(:)) ...
  1234. >= abs(r_emp_PMA.Correlation(mom))) / n_perm; % p-value after spin test
  1235. r_emp_GA.p_value(mom) = sum(abs(r_perm(:)) ...
  1236. >= abs(r_emp_GA.Correlation(mom))) / n_perm; % p-value after spin test
  1237. r_emp_PNA.p_value(mom) = sum(abs(r_perm(:)) ...
  1238. >= abs(r_emp_PNA.Correlation(mom))) / n_perm; % p-value after spin test
  1239. end
  1240. end
  1241. for supp_figure_6 = 1
  1242. moments = ["Centre of gravity", "Variance"];
  1243. % initialise table to store the correlations between the effect maps of the
  1244. % original dataset and the dataset excluding preterm (PT) infants
  1245. r_emp_PMA = table(zeros(numel(moments),1), zeros(numel(moments),1), ...
  1246. 'RowNames', moments, 'VariableNames', ["Correlation", "p_value"]);
  1247. r_emp_GA = table(zeros(numel(moments),1), zeros(numel(moments),1), ...
  1248. 'RowNames', moments, 'VariableNames', ["Correlation", "p_value"]);
  1249. r_emp_PNA = table(zeros(numel(moments),1), zeros(numel(moments),1), ...
  1250. 'RowNames', moments, 'VariableNames', ["Correlation", "p_value"]);
  1251. for mom = 1:length(moments)
  1252. if mom == 1
  1253. cog_parcel_data_PMA = moment_age_model("cog", "PMA", ...
  1254. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 0);
  1255. cog_parcel_data_PMA_no_PT = moment_age_model("cog", "PMA", ...
  1256. gen_table_economo(gen_table_economo.GA >= 37, :), uparc_economo, ...
  1257. total_num_parcels_economo, valid_parcels_economo, 0, 0);
  1258. cog_parcel_data_GA_PNA = moment_age_model("cog", ["GA", "PNA"], ...
  1259. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 0);
  1260. cog_parcel_data_GA_PNA_no_PT = moment_age_model("cog", ["GA", "PNA"], ...
  1261. gen_table_economo(gen_table_economo.GA >= 37, :), uparc_economo, ...
  1262. total_num_parcels_economo, valid_parcels_economo, 0, 0);
  1263. else
  1264. var_parcel_data_PMA = moment_age_model("variance", "PMA", ...
  1265. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 0);
  1266. var_parcel_data_PMA_no_PT = moment_age_model("variance", "PMA", ...
  1267. gen_table_economo(gen_table_economo.GA >= 37, :), uparc_economo, ...
  1268. total_num_parcels_economo, valid_parcels_economo, 0, 0);
  1269. var_parcel_data_GA_PNA = moment_age_model("variance", ["GA", "PNA"], ...
  1270. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 0);
  1271. var_parcel_data_GA_PNA_no_PT = moment_age_model("variance", ["GA", "PNA"], ...
  1272. gen_table_economo(gen_table_economo.GA >= 37, :), uparc_economo, ...
  1273. total_num_parcels_economo, valid_parcels_economo, 0, 0);
  1274. end
  1275. end
  1276. % calculate maximum absolute value for limits
  1277. min_val = min([min(cog_parcel_data_PMA(cog_parcel_data_PMA > -100)); ...
  1278. min(cog_parcel_data_PMA_no_PT(cog_parcel_data_PMA_no_PT > -100)); ...
  1279. min(cog_parcel_data_GA_PNA(cog_parcel_data_GA_PNA > -100)); ...
  1280. min(cog_parcel_data_GA_PNA_no_PT(cog_parcel_data_GA_PNA_no_PT > -100)); ...
  1281. min(var_parcel_data_PMA(var_parcel_data_PMA > -100)); ...
  1282. min(var_parcel_data_PMA_no_PT(var_parcel_data_PMA_no_PT > -100)); ...
  1283. min(var_parcel_data_GA_PNA(var_parcel_data_GA_PNA > -100)); ...
  1284. min(var_parcel_data_GA_PNA_no_PT(var_parcel_data_GA_PNA_no_PT > -100))]);
  1285. max_val = max([max(cog_parcel_data_PMA(cog_parcel_data_PMA < 100)); ...
  1286. max(cog_parcel_data_PMA_no_PT(cog_parcel_data_PMA_no_PT < 100)); ...
  1287. max(cog_parcel_data_GA_PNA(cog_parcel_data_GA_PNA < 100)); ...
  1288. max(cog_parcel_data_GA_PNA_no_PT(cog_parcel_data_GA_PNA_no_PT < 100)); ...
  1289. max(var_parcel_data_PMA(var_parcel_data_PMA < 100)); ...
  1290. max(var_parcel_data_PMA_no_PT(var_parcel_data_PMA_no_PT < 100)); ...
  1291. max(var_parcel_data_GA_PNA(var_parcel_data_GA_PNA < 100)); ...
  1292. max(var_parcel_data_GA_PNA_no_PT(var_parcel_data_GA_PNA_no_PT < 100))]);
  1293. abs_lim = max(abs(min_val), abs(max_val));
  1294. abs_lim = abs_lim + abs_lim/100;
  1295. % plot the significant effects of PMA on each moment
  1296. for mom = 1:length(moments)
  1297. if mom == 1
  1298. parcel_data_PMA = cog_parcel_data_PMA;
  1299. parcel_data_PMA_no_PT = cog_parcel_data_PMA_no_PT;
  1300. parcel_data_GA = cog_parcel_data_GA_PNA(:,1);
  1301. parcel_data_GA_no_PT = cog_parcel_data_GA_PNA_no_PT(:,1);
  1302. parcel_data_PNA = cog_parcel_data_GA_PNA(:,2);
  1303. parcel_data_PNA_no_PT = cog_parcel_data_GA_PNA_no_PT(:,2);
  1304. else
  1305. parcel_data_PMA = var_parcel_data_PMA;
  1306. parcel_data_PMA_no_PT = var_parcel_data_PMA_no_PT;
  1307. parcel_data_GA = var_parcel_data_GA_PNA(:,1);
  1308. parcel_data_GA_no_PT = var_parcel_data_GA_PNA_no_PT(:,1);
  1309. parcel_data_PNA = var_parcel_data_GA_PNA(:,2);
  1310. parcel_data_PNA_no_PT = var_parcel_data_GA_PNA_no_PT(:,2);
  1311. end
  1312. vert_data_PMA = BoSurfStatMakeParcelData(parcel_data_PMA, wk40, wk40_economo_ind);
  1313. figure; SurfStatViewData(vert_data_PMA, wk40, strcat(moments(mom), ' PMA'));
  1314. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  1315. SurfStatColLim([-abs_lim, abs_lim]);
  1316. vert_data_PMA_no_PT = BoSurfStatMakeParcelData(parcel_data_PMA_no_PT, wk40, wk40_economo_ind);
  1317. figure; SurfStatViewData(vert_data_PMA_no_PT, wk40, strcat(moments(mom), ' PMA - no PT'));
  1318. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  1319. SurfStatColLim([-abs_lim, abs_lim]);
  1320. vert_data_GA = BoSurfStatMakeParcelData(parcel_data_GA, wk40, wk40_economo_ind);
  1321. figure; SurfStatViewData(vert_data_GA, wk40, strcat(moments(mom), ' GA'));
  1322. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  1323. SurfStatColLim([-abs_lim, abs_lim]);
  1324. vert_data_GA_no_PT = BoSurfStatMakeParcelData(parcel_data_GA_no_PT, wk40, wk40_economo_ind);
  1325. figure; SurfStatViewData(vert_data_GA_no_PT, wk40, strcat(moments(mom), ' GA - no PT'));
  1326. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  1327. SurfStatColLim([-abs_lim, abs_lim]);
  1328. vert_data_PNA = BoSurfStatMakeParcelData(parcel_data_PNA, wk40, wk40_economo_ind);
  1329. figure; SurfStatViewData(vert_data_PNA, wk40, strcat(moments(mom), ' PNA'));
  1330. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  1331. SurfStatColLim([-abs_lim, abs_lim]);
  1332. vert_data_PNA_no_PT = BoSurfStatMakeParcelData(parcel_data_PNA_no_PT, wk40, wk40_economo_ind);
  1333. figure; SurfStatViewData(vert_data_PNA_no_PT, wk40, strcat(moments(mom), ' PNA - no PT'));
  1334. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  1335. SurfStatColLim([-abs_lim, abs_lim]);
  1336. % replace -100 values with NaNs for the correlation
  1337. parcel_data_PMA(parcel_data_PMA==-100)=NaN;
  1338. parcel_data_PMA_no_PT(parcel_data_PMA_no_PT==-100)=NaN;
  1339. parcel_data_GA(parcel_data_GA==-100)=NaN;
  1340. parcel_data_GA_no_PT(parcel_data_GA_no_PT==-100)=NaN;
  1341. parcel_data_PNA(parcel_data_PNA==-100)=NaN;
  1342. parcel_data_PNA_no_PT(parcel_data_PNA_no_PT==-100)=NaN;
  1343. spun_map_PMA = parcel_data_PMA(perm_id); % spin one of the PMA maps of effects
  1344. spun_map_GA = parcel_data_GA(perm_id); % spin one of the GA maps of effects
  1345. spun_map_PNA = parcel_data_PNA(perm_id); % spin one of the PNA maps of effects
  1346. r_emp_PMA.Correlation(mom)=corr(parcel_data_PMA, parcel_data_PMA_no_PT, ...
  1347. 'Rows', 'complete', 'Type', 'Pearson'); % correlate the PMA effects
  1348. r_emp_GA.Correlation(mom)=corr(parcel_data_GA, parcel_data_GA_no_PT, ...
  1349. 'Rows', 'complete', 'Type', 'Pearson'); % correlate the GA effects
  1350. r_emp_PNA.Correlation(mom)=corr(parcel_data_PNA, parcel_data_PNA_no_PT, ...
  1351. 'Rows', 'complete', 'Type', 'Pearson'); % correlate the PNA effects
  1352. % run permutation test
  1353. r_perm_PMA = zeros(n_perm,1);
  1354. r_perm_GA = zeros(n_perm,1);
  1355. r_perm_PNA = zeros(n_perm,1);
  1356. for kk=1:n_perm
  1357. r_perm_PMA(kk) = corr(spun_map_PMA(:, kk), parcel_data_PMA_no_PT, ...
  1358. 'Rows', 'complete', 'Type', 'Pearson');
  1359. r_perm_GA(kk) = corr(spun_map_GA(:, kk), parcel_data_GA_no_PT, ...
  1360. 'Rows', 'complete', 'Type', 'Pearson');
  1361. r_perm_PNA(kk) = corr(spun_map_PNA(:, kk), parcel_data_PNA_no_PT, ...
  1362. 'Rows', 'complete', 'Type', 'Pearson');
  1363. end
  1364. r_emp_PMA.p_value(mom) = sum(abs(r_perm(:)) ...
  1365. >= abs(r_emp_PMA.Correlation(mom))) / n_perm; % p-value after spin test
  1366. r_emp_GA.p_value(mom) = sum(abs(r_perm(:)) ...
  1367. >= abs(r_emp_GA.Correlation(mom))) / n_perm; % p-value after spin test
  1368. r_emp_PNA.p_value(mom) = sum(abs(r_perm(:)) ...
  1369. >= abs(r_emp_PNA.Correlation(mom))) / n_perm; % p-value after spin test
  1370. end
  1371. end
  1372. for supp_figure_7 = 1
  1373. moments = ["Centre of gravity", "Variance"];
  1374. % initialise table to store the correlations between the effect maps on
  1375. % Von Economo's parcels with the effect maps on Schaefer-200 parcels
  1376. r_emp = table(zeros(numel(moments),1), zeros(numel(moments),1), ...
  1377. 'RowNames', moments, 'VariableNames', ["Correlation", "p_value"]);
  1378. for mom = 1:length(moments)
  1379. if mom == 1
  1380. cog_parcel_data_PMA = moment_age_model("cog", "PMA", ...
  1381. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 0);
  1382. cog_parcel_data_PMA_schaefer200 = moment_age_model("cog", "PMA", ...
  1383. gen_table_schaefer200, uparc_schaefer200, ...
  1384. total_num_parcels_schaefer200, valid_parcels_schaefer200, 0, 0);
  1385. else
  1386. var_parcel_data_PMA = moment_age_model("variance", "PMA", ...
  1387. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 0);
  1388. var_parcel_data_PMA_schaefer200 = moment_age_model("variance", "PMA", ...
  1389. gen_table_schaefer200, uparc_schaefer200, ...
  1390. total_num_parcels_schaefer200, valid_parcels_schaefer200, 0, 0);
  1391. end
  1392. end
  1393. % calculate maximum absolute value for limits
  1394. min_val = min([min(cog_parcel_data_PMA(cog_parcel_data_PMA > -100)); ...
  1395. min(cog_parcel_data_PMA_schaefer200(cog_parcel_data_PMA_schaefer200 > -100));
  1396. min(var_parcel_data_PMA(var_parcel_data_PMA > -100)); ...
  1397. min(var_parcel_data_PMA_schaefer200(var_parcel_data_PMA_schaefer200 > -100))]);
  1398. max_val = max([max(cog_parcel_data_PMA(cog_parcel_data_PMA < 100)); ...
  1399. max(cog_parcel_data_PMA_schaefer200(cog_parcel_data_PMA_schaefer200 < 100)); ...
  1400. max(var_parcel_data_PMA(var_parcel_data_PMA < 100)); ...
  1401. max(var_parcel_data_PMA_schaefer200(var_parcel_data_PMA_schaefer200 < 100))]);
  1402. abs_lim = max(abs(min_val), abs(max_val));
  1403. abs_lim = abs_lim + abs_lim/100;
  1404. % plot the significant effects of PMA on each moment
  1405. for mom = 1:length(moments)
  1406. if mom == 1
  1407. parc_data_PMA = cog_parcel_data_PMA;
  1408. parc_data_PMA_schaefer200 = cog_parcel_data_PMA_schaefer200;
  1409. else
  1410. parc_data_PMA = var_parcel_data_PMA;
  1411. parc_data_PMA_schaefer200 = var_parcel_data_PMA_schaefer200;
  1412. end
  1413. vert_data_PMA = BoSurfStatMakeParcelData(parc_data_PMA, wk40, wk40_economo_ind);
  1414. figure; SurfStatViewData(vert_data_PMA, wk40, strcat(moments(mom), ' PMA'));
  1415. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  1416. SurfStatColLim([-abs_lim, abs_lim]);
  1417. vert_data_PMA_schaefer200 = BoSurfStatMakeParcelData(parc_data_PMA_schaefer200, wk40, wk40_schaefer200_ind);
  1418. vert_data_PMA_schaefer200(vert_data_PMA == -100) = -100;
  1419. figure; SurfStatViewData(vert_data_PMA_schaefer200, wk40, strcat(moments(mom), ' PMA - Schaefer-200'));
  1420. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  1421. SurfStatColLim([-abs_lim, abs_lim]);
  1422. % replace -100 values with NaNs for the correlation
  1423. parc_data_PMA(parc_data_PMA==-100)=NaN;
  1424. vert_data_PMA(vert_data_PMA==-100)=NaN;
  1425. vert_data_PMA_schaefer200(vert_data_PMA_schaefer200==-100)=NaN;
  1426. spun_map = parc_data_PMA(perm_id); % spin one of the maps of effects
  1427. r_emp.Correlation(mom)=corr(vert_data_PMA', vert_data_PMA_schaefer200', ...
  1428. 'Rows', 'complete', 'Type', 'Pearson'); % correlate the effects
  1429. % run permutation test
  1430. r_perm = zeros(n_perm,1);
  1431. for kk=1:n_perm
  1432. vert_spun_map = BoSurfStatMakeParcelData(spun_map(:, kk), wk40, wk40_economo_ind);
  1433. r_perm(kk) = corr(vert_spun_map', vert_data_PMA_schaefer200', ...
  1434. 'Rows', 'complete', 'Type', 'Pearson');
  1435. end
  1436. r_emp.p_value(mom) = sum(abs(r_perm(:)) >= abs(r_emp.Correlation(mom))) / n_perm; % p-value after spin test
  1437. end
  1438. end
  1439. for supp_figure_8_9 = 1
  1440. moments = ["Centre of gravity", "Variance"];
  1441. % initialise tables to store the correlations between the effect maps on
  1442. % Von Economo's parcels with the effect maps on Schaefer-200 parcels
  1443. r_emp_GA = table(zeros(numel(moments),1), zeros(numel(moments),1), ...
  1444. 'RowNames', moments, 'VariableNames', ["Correlation", "p_value"]);
  1445. r_emp_PNA = table(zeros(numel(moments),1), zeros(numel(moments),1), ...
  1446. 'RowNames', moments, 'VariableNames', ["Correlation", "p_value"]);
  1447. for mom = 1:length(moments)
  1448. if mom == 1
  1449. cog_parcel_data = moment_age_model("cog", ["GA", "PNA"], ...
  1450. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 0);
  1451. cog_parcel_data_schaefer200 = moment_age_model("cog", ["GA", "PNA"], ...
  1452. gen_table_schaefer200, uparc_schaefer200, ...
  1453. total_num_parcels_schaefer200, valid_parcels_schaefer200, 0, 0);
  1454. else
  1455. var_parcel_data = moment_age_model("variance", ["GA", "PNA"], ...
  1456. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 0);
  1457. var_parcel_data_schaefer200 = moment_age_model("variance", ["GA", "PNA"], ...
  1458. gen_table_schaefer200, uparc_schaefer200, ...
  1459. total_num_parcels_schaefer200, valid_parcels_schaefer200, 0, 0);
  1460. end
  1461. end
  1462. % calculate maximum absolute value for limits
  1463. min_val_GA = min([min(cog_parcel_data(cog_parcel_data(:,1) > -100, 1)); ...
  1464. min(cog_parcel_data_schaefer200(cog_parcel_data_schaefer200(:,1) > -100, 1)); ...
  1465. min(var_parcel_data(var_parcel_data(:,1) > -100, 1)); ...
  1466. min(var_parcel_data_schaefer200(var_parcel_data_schaefer200(:,1) > -100, 1))]);
  1467. max_val_GA = max([max(cog_parcel_data(cog_parcel_data(:,1) < 100, 1)); ...
  1468. max(cog_parcel_data_schaefer200(cog_parcel_data_schaefer200(:,1) < 100, 1)); ...
  1469. max(var_parcel_data(var_parcel_data(:,1) < 100, 1)); ...
  1470. max(var_parcel_data_schaefer200(var_parcel_data_schaefer200(:,1) < 100, 1))]);
  1471. abs_lim_GA = max([abs(min_val_GA), abs(max_val_GA)]);
  1472. abs_lim_GA = abs_lim_GA + abs_lim_GA/100;
  1473. min_val_PNA = min([min(cog_parcel_data(cog_parcel_data(:,2) > -100, 2)); ...
  1474. min(cog_parcel_data_schaefer200(cog_parcel_data_schaefer200(:,2) > -100, 2)); ...
  1475. min(var_parcel_data(var_parcel_data(:,2) > -100, 2)); ...
  1476. min(var_parcel_data_schaefer200(var_parcel_data_schaefer200(:,2) > -100, 2))]);
  1477. max_val_PNA = max([max(cog_parcel_data(cog_parcel_data(:,2) < 100, 2)); ...
  1478. max(cog_parcel_data_schaefer200(cog_parcel_data_schaefer200(:,2) < 100, 2)); ...
  1479. max(var_parcel_data(var_parcel_data(:,2) < 100, 2)); ...
  1480. max(var_parcel_data_schaefer200(var_parcel_data_schaefer200(:,2) < 100, 2))]);
  1481. abs_lim_PNA = max([abs(min_val_PNA), abs(max_val_PNA)]);
  1482. abs_lim_PNA = abs_lim_PNA + abs_lim_PNA/100;
  1483. % plot the significant effects of PMA on each moment
  1484. for mom = 1:length(moments)
  1485. if mom == 1
  1486. parcel_data_GA = cog_parcel_data(:,1);
  1487. parcel_data_GA_schaefer200 = cog_parcel_data_schaefer200(:,1);
  1488. parcel_data_PNA = cog_parcel_data(:,2);
  1489. parcel_data_PNA_schaefer200 = cog_parcel_data_schaefer200(:,2);
  1490. else
  1491. parcel_data_GA = var_parcel_data(:,1);
  1492. parcel_data_GA_schaefer200 = var_parcel_data_schaefer200(:,1);
  1493. parcel_data_PNA = var_parcel_data(:,2);
  1494. parcel_data_PNA_schaefer200 = var_parcel_data_schaefer200(:,2);
  1495. end
  1496. vert_data_GA = BoSurfStatMakeParcelData(parcel_data_GA, wk40, wk40_economo_ind);
  1497. figure; SurfStatViewData(vert_data_GA, wk40, strcat(moments(mom), ' GA'));
  1498. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  1499. SurfStatColLim([-abs_lim_GA, abs_lim_GA]);
  1500. vert_data_GA_schaefer200 = BoSurfStatMakeParcelData(parcel_data_GA_schaefer200, wk40, wk40_schaefer200_ind);
  1501. vert_data_GA_schaefer200(vert_data_GA == -100) = -100;
  1502. figure; SurfStatViewData(vert_data_GA_schaefer200, wk40, strcat(moments(mom), ' GA - Schaefer-200'));
  1503. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  1504. SurfStatColLim([-abs_lim_GA, abs_lim_GA]);
  1505. vert_data_PNA = BoSurfStatMakeParcelData(parcel_data_PNA, wk40, wk40_economo_ind);
  1506. figure; SurfStatViewData(vert_data_PNA, wk40, strcat(moments(mom), ' PNA'));
  1507. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  1508. SurfStatColLim([-abs_lim_PNA, abs_lim_PNA]);
  1509. vert_data_PNA_schaefer200 = BoSurfStatMakeParcelData(parcel_data_PNA_schaefer200, wk40, wk40_schaefer200_ind);
  1510. vert_data_PNA_schaefer200(vert_data_PNA == -100) = -100;
  1511. figure; SurfStatViewData(vert_data_PNA_schaefer200, wk40, strcat(moments(mom), ' PNA - Schaefer-200'));
  1512. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  1513. SurfStatColLim([-abs_lim_PNA, abs_lim_PNA]);
  1514. % replace -100 values with NaNs for the correlation
  1515. parcel_data_GA(parcel_data_GA==-100)=NaN;
  1516. vert_data_GA(vert_data_GA==-100)=NaN;
  1517. vert_data_GA_schaefer200(vert_data_GA_schaefer200==-100)=NaN;
  1518. parcel_data_PNA(parcel_data_PNA==-100)=NaN;
  1519. vert_data_PNA(vert_data_PNA==-100)=NaN;
  1520. vert_data_PNA_schaefer200(vert_data_PNA_schaefer200==-100)=NaN;
  1521. spun_map_GA = parcel_data_GA(perm_id); % spin one of the GA maps of effects
  1522. spun_map_PNA = parcel_data_PNA(perm_id); % spin one of the PNA maps of effects
  1523. r_emp_GA.Correlation(mom)=corr(vert_data_GA', vert_data_GA_schaefer200', ...
  1524. 'Rows', 'complete', 'Type', 'Pearson'); % correlate the effects
  1525. r_emp_PNA.Correlation(mom)=corr(vert_data_PNA', vert_data_PNA_schaefer200', ...
  1526. 'Rows', 'complete', 'Type', 'Pearson'); % correlate the effects
  1527. % run permutation test
  1528. r_perm_GA = zeros(n_perm,1);
  1529. r_perm_PNA = zeros(n_perm,1);
  1530. for kk=1:n_perm
  1531. vert_spun_map_GA = BoSurfStatMakeParcelData(spun_map_GA(:, kk), wk40, wk40_economo_ind);
  1532. vert_spun_map_PNA = BoSurfStatMakeParcelData(spun_map_PNA(:, kk), wk40, wk40_economo_ind);
  1533. r_perm_GA(kk) = corr(vert_spun_map_GA', vert_data_GA_schaefer200', ...
  1534. 'Rows', 'complete', 'Type', 'Pearson');
  1535. r_perm_PNA(kk) = corr(vert_spun_map_PNA', vert_data_PNA_schaefer200', ...
  1536. 'Rows', 'complete', 'Type', 'Pearson');
  1537. end
  1538. r_emp_GA.p_value(mom) = sum(abs(r_perm(:)) ...
  1539. >= abs(r_emp_GA.Correlation(mom))) / n_perm; % p-value after spin test
  1540. r_emp_PNA.p_value(mom) = sum(abs(r_perm(:)) ...
  1541. >= abs(r_emp_PNA.Correlation(mom))) / n_perm; % p-value after spin test
  1542. end
  1543. end
  1544. for supp_figure_10 = 1
  1545. min_val = 0.7;
  1546. max_val = 2.1;
  1547. for depth = 1:height(MP_parc_economo)
  1548. % average intensities per parcel for each depth
  1549. avg_intensities = mean(MP_parc_economo(depth, :, :), 3);
  1550. % mask non-cortical and limbic parcels
  1551. avg_intensities(~ismember(1:88, valid_parcels_economo)) = -100;
  1552. vert_avg_intensities = BoSurfStatMakeParcelData(avg_intensities, wk40, wk40_economo_ind);
  1553. figure; SurfStatViewData(vert_avg_intensities, wk40, strcat('Depth: ', string(depth)));
  1554. colormap([0.7 0.7 0.7; flipud(lajolla)]);
  1555. SurfStatColLim([min_val, max_val]);
  1556. end
  1557. end
  1558. for supp_figure_11 = 1
  1559. moments = ["Centre of gravity", "Variance"];
  1560. % run models for GA and PNA as predictors separately
  1561. for mom = 1:length(moments)
  1562. if mom == 1
  1563. cog_parcel_data_GA = moment_age_model("cog", "GA", ...
  1564. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 0);
  1565. cog_parcel_data_PNA = moment_age_model("cog", "PNA", ...
  1566. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 0);
  1567. else
  1568. var_parcel_data_GA = moment_age_model("variance", "GA", ...
  1569. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 0);
  1570. var_parcel_data_PNA = moment_age_model("variance", "PNA", ...
  1571. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 0);
  1572. end
  1573. end
  1574. % calculate maximum absolute value for limits for each age-metric separately
  1575. min_val = min([min(cog_parcel_data_GA(cog_parcel_data_GA > -100, 1)); ...
  1576. min(cog_parcel_data_PNA(cog_parcel_data_PNA > -100, 1)); ...
  1577. min(var_parcel_data_GA(var_parcel_data_GA > -100, 1)); ...
  1578. min(var_parcel_data_PNA(var_parcel_data_PNA > -100, 1))]);
  1579. max_val = max([max(cog_parcel_data_GA(cog_parcel_data_GA(:,1) < 100, 1)); ...
  1580. max(cog_parcel_data_PNA(cog_parcel_data_PNA(:,1) < 100, 1)); ...
  1581. max(var_parcel_data_GA(var_parcel_data_GA(:,1) < 100, 1)); ...
  1582. max(var_parcel_data_PNA(var_parcel_data_PNA(:,1) < 100, 1))]);
  1583. abs_lim = max([abs(min_val), abs(max_val)]);
  1584. abs_lim = abs_lim + abs_lim/100;
  1585. % plot the significant effects of GA and PNA on each moment
  1586. for mom = 1:length(moments)
  1587. if mom == 1
  1588. parcel_data_GA = cog_parcel_data_GA;
  1589. parcel_data_PNA = cog_parcel_data_PNA;
  1590. else
  1591. parcel_data_GA = var_parcel_data_GA;
  1592. parcel_data_PNA = var_parcel_data_PNA;
  1593. end
  1594. vert_data_GA = BoSurfStatMakeParcelData(parcel_data_GA, wk40, wk40_economo_ind);
  1595. figure; SurfStatViewData(vert_data_GA, wk40, strcat(moments(mom), ' GA'));
  1596. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  1597. SurfStatColLim([-abs_lim, abs_lim]);
  1598. vert_data_PNA = BoSurfStatMakeParcelData(parcel_data_PNA, wk40, wk40_economo_ind);
  1599. figure; SurfStatViewData(vert_data_PNA, wk40, strcat(moments(mom), ' PNA'));
  1600. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  1601. SurfStatColLim([-abs_lim, abs_lim]);
  1602. end
  1603. end
  1604. for supp_figure_12 = 1
  1605. moments = ["Centre of gravity", "Variance"];
  1606. % initialise table to store the correlations between the effect maps
  1607. % with and without correcting for cortical thickness
  1608. r_emp = table(zeros(numel(moments),1), zeros(numel(moments),1), ...
  1609. 'RowNames', moments, 'VariableNames', ["Correlation", "p_value"]);
  1610. for mom = 1:length(moments)
  1611. if mom == 1
  1612. cog_parcel_data = moment_age_model("cog", "PMA", ...
  1613. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 0);
  1614. cog_parcel_data_thick_corr = moment_age_model("cog", "PMA", ...
  1615. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 1);
  1616. else
  1617. var_parcel_data = moment_age_model("variance", "PMA", ...
  1618. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 0);
  1619. var_parcel_data_thick_corr = moment_age_model("variance", "PMA", ...
  1620. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 1);
  1621. end
  1622. end
  1623. % calculate maximum absolute value for limits
  1624. min_val = min([min(cog_parcel_data(cog_parcel_data > -100)); ...
  1625. min(cog_parcel_data_thick_corr(cog_parcel_data_thick_corr > -100));
  1626. min(var_parcel_data(var_parcel_data > -100)); ...
  1627. min(var_parcel_data_thick_corr(var_parcel_data_thick_corr > -100))]);
  1628. max_val = max([max(cog_parcel_data(cog_parcel_data < 100)); ...
  1629. max(cog_parcel_data_thick_corr(cog_parcel_data_thick_corr < 100)); ...
  1630. max(var_parcel_data(var_parcel_data < 100)); ...
  1631. max(var_parcel_data_thick_corr(var_parcel_data_thick_corr < 100))]);
  1632. abs_lim = max(abs(min_val), abs(max_val));
  1633. abs_lim = abs_lim + abs_lim/100;
  1634. % plot the significant effects of PMA on each moment
  1635. for mom = 1:length(moments)
  1636. if mom == 1
  1637. parcel_data = cog_parcel_data;
  1638. parcel_data_thick_corr = cog_parcel_data_thick_corr;
  1639. else
  1640. parcel_data = var_parcel_data;
  1641. parcel_data_thick_corr = var_parcel_data_thick_corr;
  1642. end
  1643. vert_data = BoSurfStatMakeParcelData(parcel_data, wk40, wk40_economo_ind);
  1644. figure; SurfStatViewData(vert_data, wk40, strcat(moments(mom), ' PMA'));
  1645. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  1646. SurfStatColLim([-abs_lim, abs_lim]);
  1647. vert_data_thick_corr = BoSurfStatMakeParcelData(parcel_data_thick_corr, wk40, wk40_economo_ind);
  1648. figure; SurfStatViewData(vert_data_thick_corr, wk40, strcat(moments(mom), ' PMA - thickness correction'));
  1649. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  1650. SurfStatColLim([-abs_lim, abs_lim]);
  1651. % replace -100 values with NaNs for the correlation
  1652. parcel_data(parcel_data==-100)=NaN;
  1653. parcel_data_thick_corr(parcel_data_thick_corr==-100)=NaN;
  1654. spun_map = parcel_data(perm_id); % spin one of the maps of effects
  1655. r_emp.Correlation(mom)=corr(parcel_data, parcel_data_thick_corr, ...
  1656. 'Rows', 'complete', 'Type', 'Pearson'); % correlate the effects
  1657. % run permutation test
  1658. r_perm = zeros(n_perm,1);
  1659. for kk=1:n_perm
  1660. r_perm(kk) = corr(spun_map(:, kk), parcel_data_thick_corr, ...
  1661. 'Rows', 'complete', 'Type', 'Pearson');
  1662. end
  1663. r_emp.p_value(mom) = sum(abs(r_perm(:)) >= abs(r_emp.Correlation(mom))) / n_perm; % p-value after spin test
  1664. end
  1665. end
  1666. for supp_figure_13_14 = 1
  1667. moments = ["Centre of gravity", "Variance"];
  1668. % initialise table to store the correlations between the effect maps
  1669. % with and without correcting for cortical thickness
  1670. r_emp_GA = table(zeros(numel(moments),1), zeros(numel(moments),1), ...
  1671. 'RowNames', moments, 'VariableNames', ["Correlation", "p_value"]);
  1672. r_emp_PNA = table(zeros(numel(moments),1), zeros(numel(moments),1), ...
  1673. 'RowNames', moments, 'VariableNames', ["Correlation", "p_value"]);
  1674. % run models which contain both GA and PNA as predictors (effects
  1675. % controlling for the effects of the other)
  1676. for mom = 1:length(moments)
  1677. if mom == 1
  1678. cog_parcel_data = moment_age_model("cog", ["GA", "PNA"], ...
  1679. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 0);
  1680. cog_parcel_data_thick_corr = moment_age_model("cog", ["GA", "PNA"], ...
  1681. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 1);
  1682. else
  1683. var_parcel_data = moment_age_model("variance", ["GA", "PNA"], ...
  1684. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 0);
  1685. var_parcel_data_thick_corr = moment_age_model("variance", ["GA", "PNA"], ...
  1686. gen_table_economo, uparc_economo, total_num_parcels_economo, valid_parcels_economo, 0, 1);
  1687. end
  1688. end
  1689. % calculate maximum absolute value for limits for each age-metric separately
  1690. min_val_GA = min([min(cog_parcel_data(cog_parcel_data(:,1) > -100, 1)); ...
  1691. min(cog_parcel_data_thick_corr(cog_parcel_data_thick_corr(:,1) > -100, 1)); ...
  1692. min(var_parcel_data(var_parcel_data(:,1) > -100, 1)); ...
  1693. min(var_parcel_data_thick_corr(var_parcel_data_thick_corr(:,1) > -100, 1))]);
  1694. max_val_GA = max([max(cog_parcel_data(cog_parcel_data(:,1) < 100, 1)); ...
  1695. max(cog_parcel_data_thick_corr(cog_parcel_data_thick_corr(:,1) < 100, 1)); ...
  1696. max(var_parcel_data(var_parcel_data(:,1) < 100, 1)); ...
  1697. max(var_parcel_data_thick_corr(var_parcel_data_thick_corr(:,1) < 100, 1))]);
  1698. abs_lim_GA = max([abs(min_val_GA), abs(max_val_GA)]);
  1699. abs_lim_GA = abs_lim_GA + abs_lim_GA/100;
  1700. min_val_PNA = min([min(cog_parcel_data(cog_parcel_data(:,2) > -100, 2)); ...
  1701. min(cog_parcel_data_thick_corr(cog_parcel_data_thick_corr(:,2) > -100, 2)); ...
  1702. min(var_parcel_data(var_parcel_data(:,2) > -100, 2)); ...
  1703. min(var_parcel_data_thick_corr(var_parcel_data_thick_corr(:,2) > -100, 2))]);
  1704. max_val_PNA = max([max(cog_parcel_data(cog_parcel_data(:,2) < 100, 2)); ...
  1705. max(cog_parcel_data_thick_corr(cog_parcel_data_thick_corr(:,2) < 100, 2)); ...
  1706. max(var_parcel_data(var_parcel_data(:,2) < 100, 2)); ...
  1707. max(var_parcel_data_thick_corr(var_parcel_data_thick_corr(:,2) < 100, 2))]);
  1708. abs_lim_PNA = max([abs(min_val_PNA), abs(max_val_PNA)]);
  1709. abs_lim_PNA = abs_lim_PNA + abs_lim_PNA/100;
  1710. % plot the significant effects of GA and PNA on each moment
  1711. for mom = 1:length(moments)
  1712. if mom == 1
  1713. parcel_data_GA = cog_parcel_data(:,1);
  1714. parcel_data_GA_thick_corr = cog_parcel_data_thick_corr(:,1);
  1715. parcel_data_PNA = cog_parcel_data(:,2);
  1716. parcel_data_PNA_thick_corr = cog_parcel_data_thick_corr(:,2);
  1717. else
  1718. parcel_data_GA = var_parcel_data(:,1);
  1719. parcel_data_GA_thick_corr = var_parcel_data_thick_corr(:,1);
  1720. parcel_data_PNA = var_parcel_data(:,2);
  1721. parcel_data_PNA_thick_corr = var_parcel_data_thick_corr(:,2);
  1722. end
  1723. vert_data_PNA = BoSurfStatMakeParcelData(parcel_data_PNA, wk40, wk40_economo_ind);
  1724. figure; SurfStatViewData(vert_data_PNA, wk40, strcat(moments(mom), ' PNA'));
  1725. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  1726. SurfStatColLim([-abs_lim_PNA, abs_lim_PNA]);
  1727. vert_data_PNA_thick_corr = BoSurfStatMakeParcelData(parcel_data_PNA_thick_corr, wk40, wk40_economo_ind);
  1728. figure; SurfStatViewData(vert_data_PNA_thick_corr, wk40, strcat(moments(mom), ' PNA - thickness correction'));
  1729. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  1730. SurfStatColLim([-abs_lim_PNA, abs_lim_PNA]);
  1731. vert_data_GA = BoSurfStatMakeParcelData(parcel_data_GA, wk40, wk40_economo_ind);
  1732. figure; SurfStatViewData(vert_data_GA, wk40, strcat(moments(mom), ' GA'));
  1733. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  1734. SurfStatColLim([-abs_lim_GA, abs_lim_GA]);
  1735. vert_data_GA_thick_corr = BoSurfStatMakeParcelData(parcel_data_GA_thick_corr, wk40, wk40_economo_ind);
  1736. figure; SurfStatViewData(vert_data_GA_thick_corr, wk40, strcat(moments(mom), ' GA - thickness correction'));
  1737. colormap([0.5 0.5 0.5; vik; 0.5 0.5 0.5]);
  1738. SurfStatColLim([-abs_lim_GA, abs_lim_GA]);
  1739. % replace -100 values with NaNs for the correlation
  1740. parcel_data_GA(parcel_data_GA==-100)=NaN;
  1741. parcel_data_GA_thick_corr(parcel_data_GA_thick_corr==-100)=NaN;
  1742. parcel_data_PNA(parcel_data_PNA==-100)=NaN;
  1743. parcel_data_PNA_thick_corr(parcel_data_PNA_thick_corr==-100)=NaN;
  1744. spun_map_GA = parcel_data_GA(perm_id); % spin one of the GA maps of effects
  1745. spun_map_PNA = parcel_data_PNA(perm_id); % spin one of the PNA maps of effects
  1746. r_emp_GA.Correlation(mom)=corr(parcel_data_GA, parcel_data_GA_thick_corr, ...
  1747. 'Rows', 'complete', 'Type', 'Pearson'); % correlate the GA effects
  1748. r_emp_PNA.Correlation(mom)=corr(parcel_data_PNA, parcel_data_PNA_thick_corr, ...
  1749. 'Rows', 'complete', 'Type', 'Pearson'); % correlate the PNA effects
  1750. % run permutation test
  1751. r_perm_GA = zeros(n_perm,1);
  1752. r_perm_PNA = zeros(n_perm,1);
  1753. for kk=1:n_perm
  1754. r_perm_GA(kk) = corr(spun_map_GA(:, kk), parcel_data_GA_thick_corr, ...
  1755. 'Rows', 'complete', 'Type', 'Pearson');
  1756. r_perm_PNA(kk) = corr(spun_map_PNA(:, kk), parcel_data_PNA_thick_corr, ...
  1757. 'Rows', 'complete', 'Type', 'Pearson');
  1758. end
  1759. r_emp_GA.p_value(mom) = sum(abs(r_perm_GA(:)) ...
  1760. >= abs(r_emp_GA.Correlation(mom))) / n_perm; % p-value after spin test
  1761. r_emp_PNA.p_value(mom) = sum(abs(r_perm_PNA(:)) ...
  1762. >= abs(r_emp_PNA.Correlation(mom))) / n_perm; % p-value after spin test
  1763. end
  1764. end

infant_micro_figures.m at commit 5c4f80c, no license · at the source

Overview

Authors: Thanos Tsigaras1,2, Juergen Dukart1,2, Stuart Oldham3,4, Simon B. Eickhoff1,2, Casey Paquola1
ORCID iDs: Casey Paquola
  1. Institute for Neuroscience and Medicine (INM-7), Forschungszentrum Jülich, Jülich, Germany
  2. Institute for Systems Neuroscience, Heinrich Heine University Düsseldorf, Düsseldorf, Germany
  3. Developmental Imaging, Murdoch Children’s Research Institute, Parkville, Australia
  4. Turner Institute for Brain and Mental Health, Monash University, Melbourne, Australia
Journal: PLoS biology, volume 24, issue 3, article e3003722
Dates: received 12 August 2025; accepted 9 March 2026; published online 26 March 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI 10.1371/journal.pbio.3003722 · PMID 41886498 · PMCID PMC13046243 · OpenAlex W7140585155
Open access: gold, a free copy (OpenAlex)
Status: code verified (how the code is found and verified)
Categories: structural MRI / diffusion (modality), human (organism), developmental (subfield)
Methods: Connectivity, Statistics, Preprocessing, Machine learning, fMRI & imaging
MeSH: Cerebral Cortex*, Myelin Sheath*, Female, Gestational Age, Humans, Infant, Newborn, Magnetic Resonance Imaging, Male, Neurodevelopment, Pregnancy (* major topic)
Journal subjects: Physical Sciences, Materials Science, Materials Physics, Microstructure, Physics, Medicine and Health Sciences, Diagnostic Medicine, Diagnostic Radiology, Magnetic Resonance Imaging, Research and Analysis Methods, Imaging Techniques, Radiology and Imaging, Mathematical and Statistical Techniques, Statistical Methods, Regression Analysis, Linear Regression Analysis, Mathematics, Statistics, Discrete Mathematics, Combinatorics, Permutation, Biology and Life Sciences, Neuroscience, Cognitive Science, Cognitive Psychology, Perception, Sensory Perception, Psychology, Social Sciences, Developmental Biology, Twins, Women's Health, Maternal Health, Pregnancy, Obstetrics and Gynecology, People and Places, Population Groupings, Age Groups, Children, Infants, Families
Topic: Advanced Neuroimaging Techniques and Applications (Radiology, Nuclear Medicine and Imaging, Medicine), according to OpenAlex
Funding: Deutsche Forschungsgemeinschaft (524408221); German Scholars Organisation (KT40)
Citations: cited by 1 paper (Europe PMC); 70 references in the paper

Abstract

During late gestation and early postnatal development a combination of intrinsic and extrinsic factors drive the maturation of the human cortex. This process is regionally heterogeneous, with cortical areas developing at different paces and trajectories. Leveraging submillimetre T1-weighted/T2w-weighted (T1w/T2w) magnetic resonance imaging (MRI) from pre- and full-term neonates (n = 599, 26–44 weeks), we sampled intracortical profiles across the cortex and characterized the profiles’ shapes according to their central moments. We found that gestational age at birth dominated the effects on early cortical development, with significant, global increases in intracortical homogeneity and a bimodal change in the balance of myelin-sensitive signal between superficial and deeper cortical layers. On the other hand, weeks since birth (i.e., postnatal age) exhibited different effects on myelin, with increasing intracortical heterogeneity and intracortical balance only shifting towards deeper layers in posterior temporal, occipital, medial parietal areas and some prefrontal areas. These effects align with low spatial-frequency geometric eigenmodes of the human cortex, specifically the anterior–posterior and superior-inferior axes. Our findings demonstrate that separating prenatal from postnatal influences, and analyzing intracortical profiles rather than macroscale features, provides finer-grained insights into how human cortical myelin changes during perinatal development and lays the groundwork for investigating the biological underpinnings that govern normative cortical maturation.

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

Repositories

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

ThanosTsig/InfantMicro

License: none: the authors keep all their rights
State: the link answers, verified on 30 September 2026
Evidence: files inventoried
Commit: 5c4f80c56e321abb1081aa388d2cbac5ecd67fb4, 11 March 2026
Languages: MATLAB (7)
Size: 45 files, 7 scripts
Software Heritage: not archived
Found in: “Data Availability”
Holds: README
Not found: license file, CITATION.cff, environment file, tests, continuous integration, documentation
Availability: 1 check, the latest on 30 September 2026: the link answers
  • 30 September 2026: the link answers
8 files

Zenodo 18910237

License: CC-BY-4.0
State: the link answers, verified on 30 September 2026
Evidence: files inventoried
Size: 1 file
Software Heritage: not checked
Found in: the text, “Alignment of developmental effects on myelin to ”
Not found: README, license file, CITATION.cff, environment file, tests, continuous integration, documentation
Availability: 1 check, the latest on 30 September 2026: the link answers (HTTP 200)
  • 30 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:

  • 2 repositories of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 14 scripts, each with its path and the digest of its content;
  • 4 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

Datasets cited

Data Availability

Data were obtained from the developing Human Connectome Project (https://www.developingconnectome.org/), which is openly available to download for research purposes via the NIMH data archive (https://nda.nih.gov/edit_collection.html?id=3955). Code and additional data for this study are openly available at a Github repository (https://github.com/ThanosTsig/InfantMicro) which is archived in Zenodo (https://doi.org/10.5281/zenodo.18910237).

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, 30 September 2026: the first record

Recorded: type, language, journal, volume, issue, pages, dates, 5 authors, 10 MeSH terms, 2 funders, 69 references.

Cite

This paper

Tsigaras, T., Dukart, J., Oldham, S., Eickhoff, S. B., & Paquola, C. (2026). Prenatal and early postnatal periods differentially shape the maturation of human cortical microstructure and myelin. PLoS biology, 24(3), e3003722. https://doi.org/10.1371/journal.pbio.3003722

BibTeX

@article{tsigaras2026prenatal,
author = {Tsigaras, Thanos and Dukart, Juergen and Oldham, Stuart and Eickhoff, Simon B. and Paquola, Casey},
title = {{Prenatal and early postnatal periods differentially shape the maturation of human cortical microstructure and myelin}},
journal = {PLoS biology},
year = {2026},
month = mar,
volume = {24},
number = {3},
pages = {e3003722},
publisher = {PLOS},
issn = {1544-9173},
doi = {10.1371/journal.pbio.3003722},
url = {https://doi.org/10.1371/journal.pbio.3003722},
pmid = {41886498},
pmcid = {PMC13046243}
}

RIS

TY - JOUR
AU - Tsigaras, Thanos
AU - Dukart, Juergen
AU - Oldham, Stuart
AU - Eickhoff, Simon B.
AU - Paquola, Casey
TI - Prenatal and early postnatal periods differentially shape the maturation of human cortical microstructure and myelin
T2 - PLoS biology
J2 - PLoS Biol
PY - 2026
DA - 2026/03/26
VL - 24
IS - 3
SP - e3003722
SN - 1544-9173
PB - PLOS
DO - 10.1371/journal.pbio.3003722
UR - https://doi.org/10.1371/journal.pbio.3003722
LA - en
ER -

CSL-JSON

{
"id": "10.1371/journal.pbio.3003722",
"type": "article-journal",
"title": "Prenatal and early postnatal periods differentially shape the maturation of human cortical microstructure and myelin",
"container-title": "PLoS biology",
"author": [
{
"family": "Tsigaras",
"given": "Thanos"
},
{
"family": "Dukart",
"given": "Juergen"
},
{
"family": "Oldham",
"given": "Stuart"
},
{
"family": "Eickhoff",
"given": "Simon B."
},
{
"family": "Paquola",
"given": "Casey"
}
],
"container-title-short": "PLoS Biol",
"volume": "24",
"issue": "3",
"page": "e3003722",
"DOI": "10.1371/journal.pbio.3003722",
"PMID": "41886498",
"PMCID": "PMC13046243",
"ISSN": "1544-9173",
"publisher": "PLOS",
"URL": "https://doi.org/10.1371/journal.pbio.3003722",
"language": "en",
"issued": {
"date-parts": [
[
2026,
3,
26
]
]
}
}

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.1002/hbm.26660 [code]
Feature similarity gradients detect alterations in the neonatal cortex associated with preterm birth.
Journal: Human brain mapping
In common: biomedia.github.io/dhcp-release-notes, developmental, structural MRI / diffusion, 12 references
[2] doi:10.1162/imag.a.1212 [code]
Intracortical microstructure profiling: A cross-modal method for indexing cortical lamination.
Journal: Imaging neuroscience (Cambridge, Mass.)
In common: structural MRI / diffusion, 9 references, author Casey Paquola
[3] doi:10.1371/journal.pbio.3003378 [code]
Humans have a longer period of cortical maturation across depth and hierarchy than macaques.
Journal: PLoS biology
In common: developmental, structural MRI / diffusion, 12 references
[4] doi:10.1038/s41593-024-01868-0 [code]
The architecture of the human default mode network explored through cytoarchitecture, wiring and signal flow.
Journal: Nature neuroscience
In common: GIfTI library for MATLAB, Statistics and Machine Learning Toolbox, structural MRI / diffusion, 8 references, author Casey Paquola
[5] doi:10.1038/s41467-024-51459-7 [code]
Relating sex-bias in human cortical and hippocampal microstructure to sex hormones.
Journal: Nature communications
In common: fdr_bh (Benjamini-Hochberg FDR), GIfTI library for MATLAB, Statistics and Machine Learning Toolbox, 10 references
[6] doi:10.7554/elife.78733 [code]
Development of visual cortex in human neonates is selectively modified by postnatal experience.
Journal: eLife
In common: GIfTI library for MATLAB, Statistics and Machine Learning Toolbox, structural MRI / diffusion, 10 references
[7] doi:10.1162/imag_a_00418 [code]
Perinatal development of structural thalamocortical connectivity.
Journal: Imaging neuroscience (Cambridge, Mass.)
In common: GIfTI library for MATLAB, Statistics and Machine Learning Toolbox, structural MRI / diffusion, 9 references
[8] doi:10.1371/journal.pbio.3003927 [code]
Brain structural and functional connectivity converge prenatally but diverge after birth.
Journal: PLoS biology
In common: GIfTI library for MATLAB, Statistics and Machine Learning Toolbox, biomedia.github.io/dhcp-release-notes, developmental, structural MRI / diffusion, 5 references
[9] doi:10.1038/s41467-026-70660-4 [code]
Dual-axis myelination covariance drives the functional connectivity emergence during infancy.
Journal: Nature communications
In common: Statistics and Machine Learning Toolbox, structural MRI / diffusion, 10 references
[10] doi:10.1016/j.nicl.2022.103286 [code]
Aberrant claustrum structure in preterm-born neonates: an MRI study.
Journal: NeuroImage. Clinical
In common: developmental, structural MRI / diffusion, 10 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.

Add the badge to the code's README

OSCR: the badge of this paper

If you are an author or a maintainer of this paper's code, you can add this badge. It says what OSCR knows of the paper (its code, its validated tracing map) and links the code to this page. Paste one of these snippets under the README's title. Keep the two marks around it, so that the badge can be replaced in place and is never added twice. OSCR changes nothing in your repository.

Markdown
<!-- oscr-badge:start -->
[![OSCR](https://openscicode.org/badge/doi/10.1371/journal.pbio.3003722.svg)](https://openscicode.org/badge/doi/10.1371/journal.pbio.3003722)
<!-- oscr-badge:end -->
reStructuredText
.. oscr-badge:start

.. image:: https://openscicode.org/badge/doi/10.1371/journal.pbio.3003722.svg
   :target: https://openscicode.org/badge/doi/10.1371/journal.pbio.3003722
   :alt: OSCR

.. oscr-badge:end
HTML
<!-- oscr-badge:start -->
<a href="https://openscicode.org/badge/doi/10.1371/journal.pbio.3003722"><img src="https://openscicode.org/badge/doi/10.1371/journal.pbio.3003722.svg" alt="OSCR"></a>
<!-- oscr-badge:end -->

On GitHub, open the README, choose Edit (the pencil), paste the snippet under the title, then "Commit changes".

If you choose to, you can have the badge kept up to date for you, with oscr badge --write from the command line or with the GitHub Action in your repository's workflows. Every other form and option (a card, AsciiDoc, LaTeX, shields.io) is on the badge 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: code errors and mismatches between the code and the paper about this paper and its code, from readers and its authors, beside the paper and its tracing map.

Report a mismatch between the code and the paper · Report a code error (signed in)

Reproductions: reports from readers who ran the authors' code and did not get the paper's result, what they ran, with which environment, commit and data.

Report a reproduction failure (signed in)

Versions of its code: the releases of its code tied to a version of this paper (the preprint, the accepted manuscript, the version of record…), each with the tracing map versioned with it.

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