Skip to content

[ENH] Transfer all atlases to spm atlas #100

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<atlas version="2.0">
<header>
<name>space-MNI152ICBM2009anlin_atlas-glasser_dseg</name>
<name>A multi-modal parcellation of human cerebral cortex. Glasser 2016</name>
<version>1.0</version>
<description>space-MNI152ICBM2009anlin_atlas-glasser_dseg</description>
<url></url>
Expand Down
41 changes: 41 additions & 0 deletions atlas/space-MNI_atlas-wang_dseg.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<atlas version="2.0">
<header>
<name>Probabilistic Maps of Visual Topography in Human Cortex. Wang 2015.</name>
<version>1.0</version>
<description>space-MNI_atlas-wang_dseg</description>
<url />
<licence />
<coordinate_system>MNI</coordinate_system>
<type>Label</type>
<images>
<imagefile>space-MNI_atlas-wang_dseg.nii</imagefile>
</images>
</header>
<data>
<label><index>1</index><name>V1v</name></label>
<label><index>2</index><name>V1d</name></label>
<label><index>3</index><name>V2v</name></label>
<label><index>4</index><name>V2d</name></label>
<label><index>5</index><name>V3v</name></label>
<label><index>6</index><name>V3d</name></label>
<label><index>7</index><name>hV4</name></label>
<label><index>8</index><name>VO1</name></label>
<label><index>9</index><name>VO2</name></label>
<label><index>10</index><name>PHC1</name></label>
<label><index>11</index><name>PHC2</name></label>
<label><index>12</index><name>MST</name></label>
<label><index>13</index><name>hMT</name></label>
<label><index>14</index><name>LO2</name></label>
<label><index>15</index><name>LO1</name></label>
<label><index>16</index><name>V3b</name></label>
<label><index>17</index><name>V3a</name></label>
<label><index>18</index><name>IPS0</name></label>
<label><index>19</index><name>IPS1</name></label>
<label><index>20</index><name>IPS2</name></label>
<label><index>21</index><name>IPS3</name></label>
<label><index>22</index><name>IPS4</name></label>
<label><index>23</index><name>IPS5</name></label>
<label><index>24</index><name>SPL1</name></label>
<label><index>25</index><name>FEF</name></label>
</data>
</atlas>
5 changes: 2 additions & 3 deletions atlas/update_atlas_xml.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,15 @@

lut_file = (
Path(__file__).parent
/ "Glasser"
/ "visual_topography_probability_atlas"
/ "LUT.csv"
)

df = pd.read_csv(lut_file, sep=",")

xml_file = (
Path(__file__).parent
/ "Glasser"
/ "space-MNI152ICBM2009anlin_atlas-glasser_dseg.xml"
/ "space-MNI_atlas-wang_dseg.xml"
)

mytree = ET.parse(xml_file)
Expand Down
49 changes: 49 additions & 0 deletions atlas/visfAtlas/space-MNI_atlas-visfAtlas_dseg.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<atlas version="2.0">
<header>
<name>A probabilistic functional parcellation of human occipito-temporal cortex. Rosenke 2020.</name>
<version>1.0</version>
<description>space-MNI_atlas-visfAtlas_dseg</description>
<url />
<licence />
<coordinate_system>MNI</coordinate_system>
<type>Label</type>
<images>
<imagefile>space-MNI_atlas-visfAtlas_dseg.nii</imagefile>
</images>
</header>
<data>
<label><index>1</index><name>lh_mFus</name></label>
<label><index>2</index><name>lh_pFus</name></label>
<label><index>3</index><name>lh_IOG</name></label>
<label><index>4</index><name>lh_OTS</name></label>
<label><index>5</index><name>lh_ITG</name></label>
<label><index>6</index><name>lh_MTG</name></label>
<label><index>7</index><name>lh_LOS</name></label>
<label><index>8</index><name>lh_pOTS</name></label>
<label><index>9</index><name>lh_IOS</name></label>
<label><index>10</index><name>lh_CoS</name></label>
<label><index>11</index><name>lh_hMT</name></label>
<label><index>12</index><name>lh_v1d</name></label>
<label><index>13</index><name>lh_v2d</name></label>
<label><index>14</index><name>lh_v3d</name></label>
<label><index>15</index><name>lh_v1v</name></label>
<label><index>16</index><name>lh_v2v</name></label>
<label><index>17</index><name>lh_v3v</name></label>
<label><index>18</index><name>rh_mFus</name></label>
<label><index>19</index><name>rh_pFus</name></label>
<label><index>20</index><name>rh_IOG</name></label>
<label><index>21</index><name>rh_OTS</name></label>
<label><index>22</index><name>rh_ITG</name></label>
<label><index>23</index><name>rh_MTG</name></label>
<label><index>24</index><name>rh_LOS</name></label>
<label><index>25</index><name>rh_CoS</name></label>
<label><index>26</index><name>rh_TOS</name></label>
<label><index>27</index><name>rh_hMT</name></label>
<label><index>28</index><name>rh_v1d</name></label>
<label><index>29</index><name>rh_v2d</name></label>
<label><index>30</index><name>rh_v3d</name></label>
<label><index>31</index><name>rh_v1v</name></label>
<label><index>32</index><name>rh_v2v</name></label>
<label><index>33</index><name>rh_v3v</name></label>
</data>
</atlas>
2 changes: 2 additions & 0 deletions initCppRoi.m
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ function initCppRoi()
copyAtlasToSpmDir('HCPex', 'verbose', true);
copyAtlasToSpmDir('AAL', 'verbose', true);
copyAtlasToSpmDir('Glasser', 'verbose', true);
copyAtlasToSpmDir('Wang', 'verbose', true);
copyAtlasToSpmDir('visfAtlas', 'verbose', true);

CPP_ROI_INITIALIZED = true();

Expand Down
93 changes: 67 additions & 26 deletions src/atlas/copyAtlasToSpmDir.m
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ function copyAtlasToSpmDir(varargin)
%
% copyAtlasToSpmDir(atlas, 'verbose', false)
%
% :param atlas: Any of ``{'AAL'}``. Defaults to ``'AAL'``
% :param atlas: Any of ``{'aal', 'hcpex', 'glasser', 'visfatlas', 'wang'}``.
% Defaults to ``'AAL'``
% :type atlas: char
%
% :param verbose: Defaults to ``false``
Expand All @@ -16,8 +17,6 @@ function copyAtlasToSpmDir(varargin)

% (C) Copyright 2022 CPP ROI developers

SUPPORTED_ATLASES = {'aal', 'hcpex'};

args = inputParser;

addOptional(args, 'atlas', 'AAL', @ischar);
Expand All @@ -30,29 +29,7 @@ function copyAtlasToSpmDir(varargin)

spmAtlasDir = fullfile(spm('dir'), 'atlas');

switch lower(atlas)

case 'aal'
sourceAtlasImage = fullfile(returnAtlasDir(), 'AAL3', 'AAL3v1_1mm.nii.gz');
sourceAtlasXml = fullfile(returnAtlasDir(), 'AAL3', 'AAL3v1_1mm.xml');

case 'hcpex'
unzipAtlas(lower(atlas));
sourceAtlasImage = fullfile(returnAtlasDir(lower(atlas)), 'HCPex.nii');
sourceAtlasXml = fullfile(returnAtlasDir(), 'HCPex.xml');

case 'glasser'
unzipAtlas(lower(atlas));
sourceAtlasImage = fullfile(returnAtlasDir(lower(atlas)), ...
'space-MNI152ICBM2009anlin_atlas-glasser_dseg.nii');
sourceAtlasXml = fullfile(returnAtlasDir(lower(atlas)), ...
'space-MNI152ICBM2009anlin_atlas-glasser_dseg.xml');

otherwise
error(['Only the following atlases can be copied to SPM atlas folder:\n', ...
bids.internal.create_unordered_list(SUPPORTED_ATLASES)]);

end
[sourceAtlasImage, sourceAtlasXml] = prepareFiles(atlas);

targetAtlasImage = fullfile(spmAtlasDir, spm_file(sourceAtlasImage, 'filename'));
targetAtlasXml = fullfile(spmAtlasDir, spm_file(sourceAtlasXml, 'filename'));
Expand Down Expand Up @@ -90,4 +67,68 @@ function copyAtlasToSpmDir(varargin)

end

if strcmpi(atlas, 'wang')
delete(sourceAtlasImage);
end

end

function [sourceAtlasImage, sourceAtlasXml] = prepareFiles(atlas)

SUPPORTED_ATLASES = {'aal', 'hcpex', 'glasser', 'visfatlas', 'wang'};

atlas = lower(atlas);
switch atlas

case 'aal'
sourceAtlasImage = fullfile(returnAtlasDir(), 'AAL3', 'AAL3v1_1mm.nii.gz');
sourceAtlasXml = fullfile(returnAtlasDir(), 'AAL3', 'AAL3v1_1mm.xml');

case 'hcpex'
sourceAtlasImage = fullfile(returnAtlasDir(atlas), 'HCPex.nii');
sourceAtlasXml = fullfile(returnAtlasDir(), 'HCPex.xml');

case 'visfatlas'
sourceAtlasImage = fullfile(returnAtlasDir(atlas), 'space-MNI_atlas-visfAtlas_dseg.nii');
sourceAtlasXml = fullfile(returnAtlasDir(atlas), 'space-MNI_atlas-visfAtlas_dseg.xml');

case 'glasser'

sourceAtlasImage = fullfile(returnAtlasDir(atlas), ...
'space-MNI152ICBM2009anlin_atlas-glasser_dseg.nii');
sourceAtlasXml = fullfile(returnAtlasDir(atlas), ...
'space-MNI152ICBM2009anlin_atlas-glasser_dseg.xml');

case 'wang'
sourceAtlasImage = fullfile(returnAtlasDir(atlas), ...
'subj_vol_all', ...
'space-MNI_atlas-wang_dseg.nii');
sourceAtlasXml = fullfile(returnAtlasDir(), ...
'space-MNI_atlas-wang_dseg.xml');

otherwise
error(['Only the following atlases can be copied to SPM atlas folder:\n', ...
bids.internal.create_unordered_list(SUPPORTED_ATLASES)]);

end

if ismember(atlas, {'hcpex', 'glasser', 'visfatlas', 'wang'})
if exist(sourceAtlasImage, 'file') ~= 2
unzipAtlas(atlas);
end
end

if strcmp(atlas, 'wang')
% merge left and right
files = spm_select('FPList', ...
fullfile(returnAtlasDir(lower(atlas)), 'subj_vol_all'), ...
'^space.*hemi.*nii$');
hdr = spm_vol(files);
vols = spm_read_vols(hdr);
vol = sum(vols, 4);
hdr = hdr(1);
hdr(1).fname = sourceAtlasImage;
spm_write_vol(hdr, vol);
end

end
4 changes: 3 additions & 1 deletion src/atlas/extractRoiFromAtlas.m
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,9 @@
roiIdx = strcmp([hemisphere '_' roiName], lut.ROI);

case 'glasser'

warning(['The volumetric version of the Glasser atlas is not ideally suited ', ...
'to be used for standard brain-mapping approaches ', ...
'that use volumetric nonlinear deformations.']);
roiIdx = strcmp(roiName, lut.ROI);

end
Expand Down
55 changes: 43 additions & 12 deletions tests/test_copyAtlasToSpmDir.m
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,39 @@
initTestSuite;
end

function test_copyAtlasToSpmDir_glasser()
function test_copyAtlasToSpmDir_wang()

if bids.internal.is_github_ci()
return
end
copyAtlasToSpmDir('wang', 'verbose', false);

targetAtlasImage = fullfile(spmAtlasDir(), ...
'space-MNI_atlas-wang_dseg.nii');
targetAtlasXml = fullfile(spmAtlasDir(), ...
'space-MNI_atlas-wang_dseg.xml');

assertEqual(exist(targetAtlasImage, 'file'), 2);
assertEqual(exist(targetAtlasXml, 'file'), 2);

cleanSpmAtlasDir();

end

function test_copyAtlasToSpmDir_visfatlas()

copyAtlasToSpmDir('visfatlas', 'verbose', false);

targetAtlasImage = fullfile(spmAtlasDir(), ...
'space-MNI_atlas-visfAtlas_dseg.nii');
targetAtlasXml = fullfile(spmAtlasDir(), ...
'space-MNI_atlas-visfAtlas_dseg.xml');

assertEqual(exist(targetAtlasImage, 'file'), 2);
assertEqual(exist(targetAtlasXml, 'file'), 2);

cleanSpmAtlasDir();

end

function test_copyAtlasToSpmDir_glasser()

copyAtlasToSpmDir('Glasser', 'verbose', false);

Expand All @@ -23,14 +51,12 @@ function test_copyAtlasToSpmDir_glasser()
assertEqual(exist(targetAtlasImage, 'file'), 2);
assertEqual(exist(targetAtlasXml, 'file'), 2);

cleanSpmAtlasDir();

end

function test_copyAtlasToSpmDir_basic()

if bids.internal.is_github_ci()
return
end

copyAtlasToSpmDir('AAL', 'verbose', false);

targetAtlasImage = fullfile(spmAtlasDir(), 'AAL3v1_1mm.nii');
Expand All @@ -39,14 +65,12 @@ function test_copyAtlasToSpmDir_basic()
assertEqual(exist(targetAtlasImage, 'file'), 2);
assertEqual(exist(targetAtlasXml, 'file'), 2);

cleanSpmAtlasDir();

end

function test_copyAtlasToSpmDir_HPCex()

if bids.internal.is_github_ci()
return
end

copyAtlasToSpmDir('HCPex', 'verbose', false);

targetAtlasImage = fullfile(spmAtlasDir(), 'HCPex.nii');
Expand All @@ -55,8 +79,15 @@ function test_copyAtlasToSpmDir_HPCex()
assertEqual(exist(targetAtlasImage, 'file'), 2);
assertEqual(exist(targetAtlasXml, 'file'), 2);

cleanSpmAtlasDir();

end

function value = spmAtlasDir()
value = fullfile(spm('dir'), 'atlas');
end

function cleanSpmAtlasDir()
delete(fullfile(spmAtlasDir, '*.nii'));
delete(fullfile(spmAtlasDir, '*.xml'));
end