Commit 1b98cbce authored by Paul McCarthy's avatar Paul McCarthy 🚵
Browse files

Merge branch 'various_fixes' into 'master'

Various fixes

See merge request fsl/fslpy!103
parents 62c51e9e 3c678cf9
Pipeline #3415 failed with stages
in 1 minute and 28 seconds
......@@ -193,9 +193,9 @@ Assuming that the input T1w's already exist, we can then simply run BET for ever
from fsl.utils.filetree import FileTree
from fsl.wrappers.bet import bet
tree = FileTree.read(<tree filename>)
variables = tree.get_all_vars('T1w') # extract the set of variables for all existing T1w files
for single_variable_set in variables:
T1w_tree = tree.update(**single_variable_set)
# Iterates over set of variables that correspond to each T1-weighted image file matching the template
for T1w_tree in tree.get_all_trees('T1w', glob_vars='all'):
# get retrieves the filenames based on the current set of variables
# make_dir=True ensures that the output directory containing the "bet_output" actually exists
bet(input=T1w_tree.get('T1w'), output=T1w_tree.get('bet_output', make_dir=True), mask=True)
......
......@@ -171,7 +171,7 @@ class FileTree(object):
:return: sorted sequence of paths
"""
text, variables = self.get_template(short_name)
return tuple(utils.get_all(text, variables, glob_vars=glob_vars))
return tuple(str(Path(fn)) for fn in utils.get_all(text, variables, glob_vars=glob_vars))
def get_all_vars(self, short_name: str, glob_vars=()) -> Tuple[Dict[str, str]]:
"""
......@@ -185,16 +185,33 @@ class FileTree(object):
"""
return tuple(self.extract_variables(short_name, fn) for fn in self.get_all(short_name, glob_vars=glob_vars))
def get_all_trees(self, short_name: str, global_vars=()) -> Tuple["FileTree"]:
"""
Gets all the trees that generate the existing files matching the pattern
tree.get_all(short_name) == tuple(tree.get(short_name) for tree in tree.get_all_trees(short_name))
:param short_name: short name of the path template
:param glob_vars: sequence of undefined variables that can take any possible values when looking for matches on the disk.
Any defined variables in `glob_vars` will be ignored.
If glob_vars is set to 'all', all undefined variables will be used to look up matches.
:return: sequence of FileTrees used to generate each file on disk matching the pattern of `short_name`
"""
return tuple(self.update(**vars) for vars in self.get_all_vars(short_name, glob_vars=global_vars))
def update(self, **variables) -> "FileTree":
"""
Creates a new filetree with updated variables
Creates a new FileTree with updated variables
:param variables: new values for the variables
Setting variables to None will explicitly unset them
Setting a variable to None will cause the variable to be unset
:return: New FileTree with same templates for directory names and filenames, but updated variables
"""
new_tree = deepcopy(self)
new_tree.variables.update(variables)
for key, value in variables.items():
if value is None:
del new_tree.variables[key]
return new_tree
def extract_variables(self, short_name: str, filename: str) -> Dict[str, str]:
......
......@@ -170,6 +170,8 @@ def extract_variables(template, filename, known_vars=None):
raise ValueError('Multiple values found for {}'.format(var))
else:
extracted_value[var] = value
if any('/' in value for value in extracted_value.values()):
continue
for name in find_variables(template):
if name not in extracted_value:
extracted_value[name] = None
......
......@@ -77,8 +77,8 @@ def test_custom_tree():
assert len(tree.get_all('sub_file', glob_vars='all')) == 2
assert len(tree.get_all('sub_file')) == 1
assert len(tree.update(opt=None).get_all('sub_file')) == 1
assert len(tree.update(opt=None).get_all('sub_file', glob_vars=['opt'])) == 1
assert len(tree.update(opt=None).get_all('sub_file', glob_vars='all')) == 1
assert len(tree.update(opt=None).get_all('sub_file', glob_vars=['opt'])) == 2
assert len(tree.update(opt=None).get_all('sub_file', glob_vars='all')) == 2
for fn, settings in zip(tree.get_all('sub_file', glob_vars='all'),
tree.get_all_vars('sub_file', glob_vars='all')):
......@@ -90,6 +90,10 @@ def test_custom_tree():
tree.get_all('opt_file')
assert len(tree.get_all('opt_file', glob_vars=['opt'])) == 1
for short_name in ('sub_file', 'opt_file'):
for glob_vars in (['opt'], 'all'):
assert tree.get_all(short_name, glob_vars) == tuple(stree.get(short_name) for stree in tree.get_all_trees(short_name, glob_vars))
for vars in ({'opt': None}, {'opt': 'test'}):
filename = tree.update(**vars).get('sub_file')
assert vars == tree.extract_variables('sub_file', filename)
......
......@@ -21,3 +21,7 @@ def test_get_variables():
utils.extract_variables('{var}[_{other_var}]_{var}', 'test_foo_bar')
with pytest.raises(ValueError):
utils.extract_variables('bar{var}[_{other_var}]_{var}', 'test')
assert {'subject': '01', 'session': 'A'} == utils.extract_variables('sub-{subject}/[ses-{session}]/T1w.nii.gz', 'sub-01/ses-A/T1w.nii.gz')
with pytest.raises(ValueError):
utils.extract_variables('sub-{subject}/[ses-{session}]/T1w.nii.gz', 'sub-01/other/T1w.nii.gz')
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment