harmonization.config

  1import os
  2import yaml
  3
  4from glob import glob
  5
  6
  7# This huge string is dumped directly to a text file, creating the default config as is
  8default_config = """
  9# Paths can be relative or absolute, but the root needs to already be created
 10# Any subfolder (i.e. each subject has its own folder) will be created accordingly
 11# You *need* to edit the first two lines to specify where your data files are and where the results will be output
 12# Remember that absolute or relative paths are both valid
 13path: /root/path/to/all/my/data
 14outpath: /output/path/to//my/new/data
 15outfilename: harmonization_dictionary.npy
 16
 17# If an output dataset already exists, we do not overwrite it by default
 18overwrite: False
 19
 20# If globbing is allowed, a star expression needs to be a quoted string or it crashes the reader
 21# See https://en.wikipedia.org/wiki/Glob_(programming) for more info
 22# or the examples config.yaml files in the harmonization/tests/datasets folder
 23glob: True
 24dataname: '*.nii.gz'
 25
 26# If we glob, the extension of dataname is replaced to create the filenames of the remaining files
 27# If not, the filename needs to be supplied and will be loaded from the same folder as the data
 28bval: _bval
 29bvec: _bvec
 30maskname: _brain_mask.nii.gz
 31
 32block_size: 3, 3, 3, 5
 33block_up: 3, 3, 3, 5
 34use_std: False
 35positivity_D: False
 36positivity_recon: True
 37fit_intercept: True
 38center: True
 39
 40# bias_correct_std: False
 41fix_mean: False
 42use_crossval: False
 43
 44split_b0s: True
 45b0_threshold: 20
 46batchsize: 32
 47niter: 1500
 48nlambdas: 100
 49
 50# ncores can be a positive or negative number, which indicates the number of cores to use or to leave free respectively.
 51ncores: -1 # -1 will use all cores
 52"""
 53
 54
 55def write_config(filename):
 56    with open(filename, "w") as yaml_file:
 57        yaml_file.write(default_config)
 58
 59
 60def read_config(filename):
 61    with open(filename, "r") as yaml_file:
 62        yaml_content = yaml.safe_load(yaml_file)
 63    return yaml_content
 64
 65
 66def get_filenames(path, use_glob, kwargs):
 67    datasets = []
 68
 69    if kwargs['dataname'][-7:] == '.nii.gz':
 70        kwargs['ext'] = '.nii.gz'
 71    else:
 72        kwargs['ext'] = os.path.splitext(kwargs['dataname'])[1]
 73
 74    # Build the list of all datasets and supporting files
 75    if use_glob:
 76        files = os.path.join(path, '**/', kwargs['dataname'])
 77        for name in sorted(glob(files, recursive=True)):
 78            dataset = {'data': name,
 79                       'folder': None,
 80                       'mask': name.replace(kwargs['ext'], kwargs['maskname']),
 81                       'bval': name.replace(kwargs['ext'], kwargs['bval']),
 82                       'bvec': name.replace(kwargs['ext'], kwargs['bvec'])}
 83
 84            datasets += [dataset]
 85    else:
 86        paths = list(os.walk(path))
 87
 88        if len(paths) == 0:
 89            topdir = paths[0]
 90        else:
 91            topdir = paths[0][0]
 92
 93        for root, dirs, files in paths:
 94            for name in files:
 95                if name == kwargs['dataname']:
 96                    dataset = {'data': os.path.join(root, kwargs['dataname']),
 97                               'folder': os.path.relpath(root, start=topdir),
 98                               'mask': os.path.join(root, kwargs['maskname']),
 99                               'bval': os.path.join(root, kwargs['bval']),
100                               'bvec': os.path.join(root, kwargs['bvec'])}
101
102                    datasets += [dataset]
103
104    if len(datasets) == 0:
105        error = f'No datasets found with the given config file at {os.path.realpath(path)}'
106        raise ValueError(error)
107
108    return datasets
default_config = "\n# Paths can be relative or absolute, but the root needs to already be created\n# Any subfolder (i.e. each subject has its own folder) will be created accordingly\n# You *need* to edit the first two lines to specify where your data files are and where the results will be output\n# Remember that absolute or relative paths are both valid\npath: /root/path/to/all/my/data\noutpath: /output/path/to//my/new/data\noutfilename: harmonization_dictionary.npy\n\n# If an output dataset already exists, we do not overwrite it by default\noverwrite: False\n\n# If globbing is allowed, a star expression needs to be a quoted string or it crashes the reader\n# See https://en.wikipedia.org/wiki/Glob_(programming) for more info\n# or the examples config.yaml files in the harmonization/tests/datasets folder\nglob: True\ndataname: '*.nii.gz'\n\n# If we glob, the extension of dataname is replaced to create the filenames of the remaining files\n# If not, the filename needs to be supplied and will be loaded from the same folder as the data\nbval: _bval\nbvec: _bvec\nmaskname: _brain_mask.nii.gz\n\nblock_size: 3, 3, 3, 5\nblock_up: 3, 3, 3, 5\nuse_std: False\npositivity_D: False\npositivity_recon: True\nfit_intercept: True\ncenter: True\n\n# bias_correct_std: False\nfix_mean: False\nuse_crossval: False\n\nsplit_b0s: True\nb0_threshold: 20\nbatchsize: 32\nniter: 1500\nnlambdas: 100\n\n# ncores can be a positive or negative number, which indicates the number of cores to use or to leave free respectively.\nncores: -1 # -1 will use all cores\n"
def write_config(filename):
56def write_config(filename):
57    with open(filename, "w") as yaml_file:
58        yaml_file.write(default_config)
def read_config(filename):
61def read_config(filename):
62    with open(filename, "r") as yaml_file:
63        yaml_content = yaml.safe_load(yaml_file)
64    return yaml_content
def get_filenames(path, use_glob, kwargs):
 67def get_filenames(path, use_glob, kwargs):
 68    datasets = []
 69
 70    if kwargs['dataname'][-7:] == '.nii.gz':
 71        kwargs['ext'] = '.nii.gz'
 72    else:
 73        kwargs['ext'] = os.path.splitext(kwargs['dataname'])[1]
 74
 75    # Build the list of all datasets and supporting files
 76    if use_glob:
 77        files = os.path.join(path, '**/', kwargs['dataname'])
 78        for name in sorted(glob(files, recursive=True)):
 79            dataset = {'data': name,
 80                       'folder': None,
 81                       'mask': name.replace(kwargs['ext'], kwargs['maskname']),
 82                       'bval': name.replace(kwargs['ext'], kwargs['bval']),
 83                       'bvec': name.replace(kwargs['ext'], kwargs['bvec'])}
 84
 85            datasets += [dataset]
 86    else:
 87        paths = list(os.walk(path))
 88
 89        if len(paths) == 0:
 90            topdir = paths[0]
 91        else:
 92            topdir = paths[0][0]
 93
 94        for root, dirs, files in paths:
 95            for name in files:
 96                if name == kwargs['dataname']:
 97                    dataset = {'data': os.path.join(root, kwargs['dataname']),
 98                               'folder': os.path.relpath(root, start=topdir),
 99                               'mask': os.path.join(root, kwargs['maskname']),
100                               'bval': os.path.join(root, kwargs['bval']),
101                               'bvec': os.path.join(root, kwargs['bvec'])}
102
103                    datasets += [dataset]
104
105    if len(datasets) == 0:
106        error = f'No datasets found with the given config file at {os.path.realpath(path)}'
107        raise ValueError(error)
108
109    return datasets