Skip to content

Commit

Permalink
Merge pull request #1823 from FCP-INDI/RBC/atlases
Browse files Browse the repository at this point in the history
🎨 Standardize naming for atlases used in RBC
  • Loading branch information
sgiavasis authored Nov 11, 2022
2 parents 9d97eab + cfe100f commit 6f303c8
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 59 deletions.
6 changes: 3 additions & 3 deletions CPAC/pipeline/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -1785,12 +1785,12 @@ def ingress_pipeconfig_paths(cfg, rpool, unique_id, creds_path=None):
val = val.replace('${func_resolution}', cfg.registration_workflows[
'functional_registration']['func_registration_to_template'][
'output_resolution'][tag])

if desc:
template_name = lookup_identifier(val)
template_name, _template_desc = lookup_identifier(val)
if template_name:
desc = f"{template_name} - {desc}"
json_info['Description'] = f"{desc} - {val}"
json_info['Description'] = f"{desc} - {val}"
if resolution:
resolution = cfg.get_nested(cfg, res_keys)
json_info['Resolution'] = resolution
Expand Down
43 changes: 30 additions & 13 deletions CPAC/resources/templates/BIDS_identifiers.tsv
Original file line number Diff line number Diff line change
@@ -1,13 +1,30 @@
/code/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*_T1w_reference.nii.gz MNI152NLin2009cAsym
/code/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*_desc-brain_T1w.nii.gz MNI152NLin2009cAsym
/code/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*_desc-brain_mask.nii.gz MNI152NLin2009cAsym
/code/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*_desc-fMRIPrep_boldref.nii.gz MNI152NLin2009cAsym
/code/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*_label-brain_probseg.nii.gz MNI152NLin2009cAsym
/usr/share/fsl/5.0/data/standard/MNI152_T1_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*.nii.gz MNI152NLin6ASym
/usr/share/fsl/5.0/data/standard/MNI152_T1_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*_brain.nii.gz MNI152NLin6ASym
/usr/share/fsl/5.0/data/standard/MNI152_T1_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*_brain_mask.nii.gz MNI152NLin6ASym
/usr/share/fsl/5.0/data/standard/MNI152_T1_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*_brain_mask_dil.nii.gz MNI152NLin6ASym
/usr/share/fsl/5.0/data/standard/MNI152_T1_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*_symmetric.nii.gz MNI152NLin6Sym
/usr/share/fsl/5.0/data/standard/MNI152_T1_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*_brain_symmetric.nii.gz MNI152NLin6Sym
/usr/share/fsl/5.0/data/standard/MNI152_T1_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*_brain_mask_symmetric.nii.gz MNI152NLin6Sym
/usr/share/fsl/5.0/data/standard/MNI152_T1_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*_brain_mask_symmetric_dil.nii.gz MNI152NLin6Sym
/code/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*_T1w_reference.nii.gz MNI152NLin2009cAsym
/code/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*_desc-brain_T1w.nii.gz MNI152NLin2009cAsym
/code/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*_desc-brain_mask.nii.gz MNI152NLin2009cAsym
/code/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*_desc-fMRIPrep_boldref.nii.gz MNI152NLin2009cAsym
/code/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*_label-brain_probseg.nii.gz MNI152NLin2009cAsym
/usr/share/fsl/5.0/data/standard/MNI152_T1_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*.nii.gz MNI152NLin6ASym
/usr/share/fsl/5.0/data/standard/MNI152_T1_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*_brain.nii.gz MNI152NLin6ASym
/usr/share/fsl/5.0/data/standard/MNI152_T1_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*_brain_mask.nii.gz MNI152NLin6ASym
/usr/share/fsl/5.0/data/standard/MNI152_T1_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*_brain_mask_dil.nii.gz MNI152NLin6ASym
/usr/share/fsl/5.0/data/standard/MNI152_T1_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*_symmetric.nii.gz MNI152NLin6Sym
/usr/share/fsl/5.0/data/standard/MNI152_T1_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*_brain_symmetric.nii.gz MNI152NLin6Sym
/usr/share/fsl/5.0/data/standard/MNI152_T1_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*_brain_mask_symmetric.nii.gz MNI152NLin6Sym
/usr/share/fsl/5.0/data/standard/MNI152_T1_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*_brain_mask_symmetric_dil.nii.gz MNI152NLin6Sym
/ndmg_atlases/label/Human/AAL_space-MNI152NLin6_res-2x2x2.nii.gz AAL
/ndmg_atlases/label/Human/Brodmann_space-MNI152NLin6_res-2x2x2.nii.gz Brodmann
/cpac_templates/CC200.nii.gz CC 200
/cpac_templates/CC400.nii.gz CC 400
/ndmg_atlases/label/Human/Glasser_space-MNI152NLin6_res-2x2x2.nii.gz Glasser
/ndmg_atlases/label/Human/Slab907_space-MNI152NLin6_res-2x2x2.nii.gz Slab
/ndmg_atlases/label/Human/HarvardOxfordcort-maxprob-thr25_space-MNI152NLin6_res-2x2x2.nii.gz HOCPA th25
/ndmg_atlases/label/Human/HarvardOxfordsub-maxprob-thr25_space-MNI152NLin6_res-2x2x2.nii.gz HOSPA th25
/ndmg_atlases/label/Human/Juelich_space-MNI152NLin6_res-2x2x2.nii.gz Juelich
/cpac_templates/Schaefer2018_space-FSLMNI152_res-2mm_desc-200Parcels17NetworksOrder.nii.gz Schaefer2018 200p17n
/cpac_templates/Schaefer2018_space-FSLMNI152_res-2mm_desc-300Parcels17NetworksOrder.nii.gz Schaefer2018 300p17n
/cpac_templates/Schaefer2018_space-FSLMNI152_res-2mm_desc-400Parcels17NetworksOrder.nii.gz Schaefer2018 400p17n
/cpac_templates/Schaefer2018_space-FSLMNI152_res-2mm_desc-1000Parcels17NetworksOrder.nii.gz Schaefer2018 1000p17n
/ndmg_atlases/label/Human/Yeo-7_space-MNI152NLin6_res-2x2x2.nii.gz Yeo 7
/ndmg_atlases/label/Human/Yeo-7-liberal_space-MNI152NLin6_res-2x2x2.nii.gz Yeo 7liberal
/ndmg_atlases/label/Human/Yeo-17_space-MNI152NLin6_res-2x2x2.nii.gz Yeo 17
/ndmg_atlases/label/Human/Yeo-17-liberal_space-MNI152NLin6_res-2x2x2.nii.gz Yeo 17liberal
4 changes: 2 additions & 2 deletions CPAC/resources/templates/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
'''Template resources for C-PAC'''
from .lookup_table import lookup_identifier
from .lookup_table import format_identifier, lookup_identifier

__all__ = ['lookup_identifier']
__all__ = ['format_identifier', 'lookup_identifier']
75 changes: 60 additions & 15 deletions CPAC/resources/templates/lookup_table.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,58 @@
'''Utilities for determining BIDS standard template identifiers
# Copyright (C) 2022 C-PAC Developers

# This file is part of C-PAC.

# C-PAC is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the
# Free Software Foundation, either version 3 of the License, or (at your
# option) any later version.

# C-PAC is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
# License for more details.

# You should have received a copy of the GNU Lesser General Public
# License along with C-PAC. If not, see <https://www.gnu.org/licenses/>.
"""Utilities for determining BIDS standard template identifiers
(https://bids-specification.readthedocs.io/en/stable/99-appendices/08-coordinate-systems.html#standard-template-identifiers)
from in-container template paths'''
import os
import re
import numpy as np
from in-container template paths"""
from os import path as op
from re import search
from typing import Optional, Tuple
from numpy import loadtxt

LOOKUP_TABLE = {row[0]: (row[1], str(row[2]) if row[2] else None) for row in
loadtxt(op.join(op.dirname(__file__), 'BIDS_identifiers.tsv'),
dtype='str', delimiter='\t')}


def format_identifier(identifier: str, desc: Optional[str] = None) -> str:
'''Function to create an identifier string from a name and description
Parameters
----------
identifier : str
desc : str, optional
Returns
-------
str
LOOKUP_TABLE = {row[0]: row[1] for row in
np.loadtxt(os.path.join(os.path.dirname(__file__),
'BIDS_identifiers.tsv'),
dtype='str', delimiter='\t')}
Examples
--------
>>> format_identifier('CC', '200')
'CC_desc-200'
>>> format_identifier('AAL')
'AAL'
'''
if desc:
return f'{identifier}_desc-{desc}'
return identifier


def lookup_identifier(template_path: str) -> str:
def lookup_identifier(template_path: str) -> Tuple[str, None]:
'''Function to return a standard template identifier for a packaged
template, if known. Otherwise, returns the literal string
'template'
Expand All @@ -24,19 +65,23 @@ def lookup_identifier(template_path: str) -> str:
-------
identifier : str
desc : str or None
Examples
--------
>>> lookup_identifier('/usr/share/fsl/5.0/data/standard/'
... 'MNI152_T1_1mm_brain.nii.gz')
'MNI152NLin6ASym'
('MNI152NLin6ASym', None)
>>> lookup_identifier('/code/CPAC/resources/templates/'
... 'tpl-MNI152NLin2009cAsym_res-01_label-brain_'
... 'probseg.nii.gz')
'MNI152NLin2009cAsym'
('MNI152NLin2009cAsym', None)
>>> lookup_identifier('/cpac_templates/chd8_functional_template_sk.nii')
'template'
('template', None)
>>> lookup_identifier('/cpac_templates/CC200.nii.gz')
('CC', '200')
'''
for key, value in LOOKUP_TABLE.items():
if re.search(key, template_path) is not None:
if search(key, template_path) is not None:
return value
return 'template'
return 'template', None
54 changes: 29 additions & 25 deletions CPAC/utils/datasource.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@
import csv
import json
import re
from typing import Optional, Tuple
from typing import Tuple
from nipype import logging
from nipype.interfaces import utility as util
from nipype.interfaces.fsl import MultiImageMaths
from CPAC.pipeline import nipype_pipeline_engine as pe
from CPAC.resources.templates.lookup_table import format_identifier, \
lookup_identifier
from CPAC.utils import function
from CPAC.utils.interfaces.function import Function
from CPAC.utils.utils import get_scan_params
Expand Down Expand Up @@ -1016,33 +1017,36 @@ def create_roi_mask_dataflow(masks, wf_name='datasource_roi_mask'):
if mask_file.strip() == '' or mask_file.startswith('#'):
continue

base_file = os.path.basename(mask_file)
name, desc = lookup_identifier(mask_file)

try:
valid_extensions = ['.nii', '.nii.gz']

base_name = [
base_file[:-len(ext)]
for ext in valid_extensions
if base_file.endswith(ext)
][0]

if base_name in mask_dict:
raise ValueError(
'Files with same name not allowed: %s %s' % (
mask_file,
mask_dict[base_name]
)
)
if name == 'template':
base_file = os.path.basename(mask_file)

mask_dict[base_name] = mask_file
try:
valid_extensions = ['.nii', '.nii.gz']

base_name = [
base_file[:-len(ext)]
for ext in valid_extensions
if base_file.endswith(ext)
][0]

except IndexError:
# pylint: disable=raise-missing-from
raise ValueError('Error in spatial_map_dataflow: File '
f'extension of {base_file} not ".nii" or '
'.nii.gz')

except Exception as e:
raise e
else:
base_name = format_identifier(name, desc)

except IndexError as e:
raise Exception('Error in spatial_map_dataflow: '
'File extension not in .nii and .nii.gz')
if base_name in mask_dict:
raise ValueError('Duplicate templates/atlases not allowed: '
f'{mask_file} {mask_dict[base_name]}')

except Exception as e:
raise e
mask_dict[base_name] = mask_file

wf = pe.Workflow(name=wf_name)

Expand Down
2 changes: 1 addition & 1 deletion CPAC/utils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ def create_id_string(unique_id, resource, scan_id=None, template_desc=None,
"""

if atlas_id:
if '_' in atlas_id:
if not (atlas_id.count('_') == 1 and '_desc-' in atlas_id):
atlas_id = atlas_id.replace('_', '')
resource = f'atlas-{atlas_id}_{resource}'

Expand Down

0 comments on commit 6f303c8

Please sign in to comment.