Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
FSL
fslpy
Commits
287207e5
Commit
287207e5
authored
Aug 10, 2019
by
Paul McCarthy
🚵
Browse files
Merge branch 'rf/filetree_match' into 'master'
Rf/filetree match See merge request fsl/fslpy!153
parents
8cd0f064
7c3ca51d
Pipeline
#4121
passed with stages
in 15 minutes and 1 second
Changes
4
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
CHANGELOG.rst
View file @
287207e5
...
...
@@ -12,6 +12,8 @@ Changed
* The :class:`.Cache` class has a new ``lru`` option, allowing it to be used
as a least-recently-used cache.
* The :mod:`.filetree` module has been refactored to make it easier for the
:mod:`.query` module to work with file tree hierarchies.
2.5.0 (Tuesday 6th August 2019)
...
...
fsl/utils/filetree/filetree.py
View file @
287207e5
...
...
@@ -25,12 +25,14 @@ class FileTree(object):
- ``variables``: dictionary mapping variables in the templates to specific values (variables set to None are explicitly unset)
- ``sub_trees``: filename trees describing specific sub-directories
- ``parent``: parent FileTree, of which this sub-tree is a sub-directory
- ``name``: descriptive name of the tree
"""
def
__init__
(
self
,
templates
:
Dict
[
str
,
str
],
variables
:
Dict
[
str
,
Any
],
sub_trees
:
Dict
[
str
,
"FileTree"
]
=
None
,
parent
:
Optional
[
"FileTree"
]
=
None
):
sub_trees
:
Dict
[
str
,
"FileTree"
]
=
None
,
parent
:
Optional
[
"FileTree"
]
=
None
,
name
:
str
=
None
):
"""
Creates a new filename tree.
"""
...
...
@@ -40,6 +42,7 @@ class FileTree(object):
sub_trees
=
{}
self
.
sub_trees
=
sub_trees
self
.
_parent
=
parent
self
.
_name
=
name
@
property
def
parent
(
self
,
):
...
...
@@ -48,6 +51,15 @@ class FileTree(object):
"""
return
self
.
_parent
@
property
def
name
(
self
,
):
"""
Name of this ``FileTree``, or ``None`` if it has no name.
"""
return
self
.
_name
@
property
def
all_variables
(
self
,
):
"""
...
...
@@ -346,6 +358,7 @@ class FileTree(object):
filename
=
tree_name
+
'.tree'
else
:
filename
=
parse
.
search_tree
(
tree_name
)
tree_name
=
op
.
splitext
(
op
.
basename
(
filename
))[
0
]
filename
=
Path
(
filename
)
templates
=
{}
...
...
@@ -384,6 +397,7 @@ class FileTree(object):
raise
ValueError
(
"Name of sub_tree {short_name} used multiple times in {tree_name}.tree"
.
format
(
**
locals
()))
sub_trees
[
short_name
]
=
sub_tree
sub_tree
.
_name
=
short_name
elif
'='
in
line
:
key
,
value
=
line
.
split
(
'='
)
if
len
(
key
.
split
())
!=
1
:
...
...
@@ -413,7 +427,7 @@ class FileTree(object):
templates
[
short_name
]
=
str
(
current_filename
)
file_variables
.
update
(
variables
)
res
=
get_registered
(
tree_name
,
cls
)(
templates
,
variables
=
file_variables
,
sub_trees
=
sub_trees
)
res
=
get_registered
(
tree_name
,
cls
)(
templates
,
variables
=
file_variables
,
sub_trees
=
sub_trees
,
name
=
tree_name
)
for
tree
in
sub_trees
.
values
():
tree
.
_parent
=
res
return
res
...
...
fsl/utils/filetree/query.py
View file @
287207e5
...
...
@@ -30,7 +30,8 @@ from typing import Dict, List, Tuple
import
numpy
as
np
from
.
import
FileTree
from
fsl.utils.deprecated
import
deprecated
from
.
import
FileTree
log
=
logging
.
getLogger
(
__name__
)
...
...
@@ -44,11 +45,11 @@ class FileTreeQuery(object):
by a :class:`.FileTree`, and identifies all file types (a.k.a. *templates*
or *short names*) that are present, and the values of variables within each
short name that are present. The :meth:`query` method can be used to
retrieve files which match a specific
short nam
e, and variable values.
retrieve files which match a specific
templat
e, and variable values.
The :meth:`query` method returns a multi-dimensional ``numpy.array``
which contains :class:`Match` objects, where each dimension one
represents variable for the
short nam
e in question.
represents variable for the
templat
e in question.
Example usage::
...
...
@@ -71,15 +72,13 @@ class FileTreeQuery(object):
'session': [None]}
>>> query.query('anat_image', participant='01')
array([[[[[[[Match(./my_bids_data/sub-01/anat/sub-01_T1w.nii.gz)],
[nan],
[nan],
[nan]]]],
[[[[Match(./my_bids_data/sub-01/anat/sub-01_T2w.nii.gz)],
[nan],
[nan],
[nan]]]]]]], dtype=object)
[Match(./my_bids_data/sub-01/anat/sub-01_T1w.nii.gz),
Match(./my_bids_data/sub-01/anat/sub-01_T2w.nii.gz)]
Matches for templates contained within sub-trees are referred to by
constructing a hierarchical path from the sub-tree template name(s),
and the template name - see the :meth:`Match.full_name` method.
"""
...
...
@@ -93,115 +92,132 @@ class FileTreeQuery(object):
# Find all files present in the directory
# (as Match objects), and find all variables,
# plus their values, and all
short nam
es,
# plus their values, and all
templat
es,
# that are present in the directory.
matches
=
scan
(
tree
)
allvars
,
shortnam
evars
=
allVariables
(
tree
,
matches
)
matches
=
scan
(
tree
)
allvars
,
templat
evars
=
allVariables
(
tree
,
matches
)
# Now we are going to build a series of ND
# arrays to store Match objects. We create
# one array for each
short nam
e. Each axis
# one array for each
templat
e. Each axis
# in an array corresponds to a variable
# present in files of that
short nam
e type,
# present in files of that
templat
e type,
# and each position along an axis corresponds
# to one value of that variable.
#
# These arrays will be used to store and
# retrieve Match objects - given a
short
#
name
and a set of variable values, we
#
can
quickly find the corresponding Match
# retrieve Match objects - given a
template
# and a set of variable values, we
can
# quickly find the corresponding Match
# object (or objects).
# matcharrays contains {
shortnam
e : ndarray}
# matcharrays contains {
templat
e : ndarray}
# mappings, and varidxs contains
# {
shortnam
e : {varvalue : index}} mappings
# {
templat
e : {varvalue : index}} mappings
matcharrays
=
{}
varidxs
=
{}
for
shortname
in
shortnam
evars
.
key
s
():
for
template
,
tvars
in
templat
evars
.
item
s
():
snvars
=
shortnamevars
[
shortname
]
snvarlens
=
[
len
(
allvars
[
v
])
for
v
in
snvars
]
tvarlens
=
[
len
(
allvars
[
v
])
for
v
in
tvars
]
# An ND array for this short
# name. Each element is a
# Match object, or nan.
matcharray
=
np
.
zeros
(
sn
varlens
,
dtype
=
np
.
object
)
matcharray
=
np
.
zeros
(
t
varlens
,
dtype
=
np
.
object
)
matcharray
[:]
=
np
.
nan
# indices into the match array
# for each variable value
sn
varidxs
=
{}
for
v
in
sn
vars
:
sn
varidxs
[
v
]
=
{
n
:
i
for
i
,
n
in
enumerate
(
allvars
[
v
])}
t
varidxs
=
{}
for
v
in
t
vars
:
t
varidxs
[
v
]
=
{
n
:
i
for
i
,
n
in
enumerate
(
allvars
[
v
])}
matcharrays
[
shortnam
e
]
=
matcharray
varidxs
[
shortnam
e
]
=
sn
varidxs
matcharrays
[
templat
e
]
=
matcharray
varidxs
[
templat
e
]
=
t
varidxs
# Populate the match arrays
for
match
in
matches
:
sn
vars
=
shortnam
evars
[
match
.
short
_name
]
sn
varidxs
=
varidxs
[
match
.
short
_name
]
sn
arr
=
matcharrays
[
match
.
short
_name
]
idx
=
[]
for
var
in
sn
vars
:
t
vars
=
templat
evars
[
match
.
full
_name
]
t
varidxs
=
varidxs
[
match
.
full
_name
]
t
arr
=
matcharrays
[
match
.
full
_name
]
idx
=
[]
for
var
in
t
vars
:
val
=
match
.
variables
[
var
]
idx
.
append
(
sn
varidxs
[
var
][
val
])
idx
.
append
(
t
varidxs
[
var
][
val
])
sn
arr
[
tuple
(
idx
)]
=
match
t
arr
[
tuple
(
idx
)]
=
match
self
.
__tree
=
tree
self
.
__allvars
=
allvars
self
.
__
shortnam
evars
=
shortnam
evars
self
.
__
templat
evars
=
templat
evars
self
.
__matches
=
matches
self
.
__matcharrays
=
matcharrays
self
.
__varidxs
=
varidxs
def
axes
(
self
,
short_nam
e
)
->
List
[
str
]:
def
axes
(
self
,
templat
e
)
->
List
[
str
]:
"""Returns a list containing the names of variables present in files
of the given ``
short_nam
e`` type, in the same order of the axes of
of the given ``
templat
e`` type, in the same order of the axes of
:class:`Match` arrays that are returned by the :meth:`query` method.
"""
return
self
.
__
shortnamevars
[
short_nam
e
]
return
self
.
__
templatevars
[
templat
e
]
def
variables
(
self
,
short_nam
e
=
None
)
->
Dict
[
str
,
List
]:
def
variables
(
self
,
templat
e
=
None
)
->
Dict
[
str
,
List
]:
"""Return a dict of ``{variable : [values]}`` mappings.
This dict describes all variables and their possible values in
the tree.
If a ``
short_nam
e`` is specified, only variables which are present in
files of that ``
short_nam
e`` type are returned.
If a ``
templat
e`` is specified, only variables which are present in
files of that ``
templat
e`` type are returned.
"""
if
short_nam
e
is
None
:
if
templat
e
is
None
:
return
{
var
:
list
(
vals
)
for
var
,
vals
in
self
.
__allvars
.
items
()}
else
:
varnames
=
self
.
__
shortnamevars
[
short_nam
e
]
varnames
=
self
.
__
templatevars
[
templat
e
]
return
{
var
:
list
(
self
.
__allvars
[
var
])
for
var
in
varnames
}
@
property
def
tree
(
self
):
"""Returns the :class:`.FileTree` associated with this
``FileTreeQuery``.
"""
return
self
.
__tree
@
property
def
templates
(
self
)
->
List
[
str
]:
"""Returns a list containing all templates of the ``FileTree`` that
are present in the directory.
"""
return
list
(
self
.
__templatevars
.
keys
())
@
property
@
deprecated
(
'2.6.0'
,
'3.0.0'
,
'Use templates instead'
)
def
short_names
(
self
)
->
List
[
str
]:
"""Returns a list containing all
short nam
es of the ``FileTree`` that
"""Returns a list containing all
templat
es of the ``FileTree`` that
are present in the directory.
"""
return
list
(
self
.
__shortnamevars
.
keys
())
return
self
.
templates
def
query
(
self
,
short_nam
e
,
asarray
=
False
,
**
variables
):
"""Search for files of the given ``
short_nam
e``, which match
def
query
(
self
,
templat
e
,
asarray
=
False
,
**
variables
):
"""Search for files of the given ``
templat
e``, which match
the specified ``variables``. All hits are returned for variables
that are unspecified.
:arg
short_name: Short nam
e of files to search for.
:arg
template: Templat
e of files to search for.
:arg asarray: If ``True``, the relevant :class:`Match` objects are
returned in a in a ND ``numpy.array`` where each
dimension corresponds to a variable for the
``
short_name
`` in question (as returned by
:meth:`axes`). Otherwise (the default), they are
returned in a list.
:arg asarray:
If ``True``, the relevant :class:`Match` objects are
returned in a in a ND ``numpy.array`` where each
dimension corresponds to a variable for the
``
templates
`` in question (as returned by
:meth:`axes`). Otherwise (the default), they are
returned in a list.
All other arguments are assumed to be ``variable=value`` pairs,
used to restrict which matches are returned. All values are returned
...
...
@@ -213,9 +229,9 @@ class FileTreeQuery(object):
"""
varnames
=
list
(
variables
.
keys
())
allvarnames
=
self
.
__
shortnamevars
[
short_nam
e
]
varidxs
=
self
.
__varidxs
[
short_nam
e
]
matcharray
=
self
.
__matcharrays
[
short_nam
e
]
allvarnames
=
self
.
__
templatevars
[
templat
e
]
varidxs
=
self
.
__varidxs
[
templat
e
]
matcharray
=
self
.
__matcharrays
[
templat
e
]
slc
=
[]
for
var
in
allvarnames
:
...
...
@@ -244,16 +260,18 @@ class Match(object):
"""
def
__init__
(
self
,
filename
,
short_nam
e
,
variables
):
def
__init__
(
self
,
filename
,
template
,
tre
e
,
variables
):
"""Create a ``Match`` object. All arguments are added as attributes.
:arg filename: name of existing file
:arg short_name: template identifier
:arg template: template identifier
:arg tree: :class:`.FileTree` which contains this ``Match``
:arg variables: Dictionary of ``{variable : value}`` mappings
containing all variables present in the file name.
"""
self
.
__filename
=
filename
self
.
__short_name
=
short_name
self
.
__template
=
template
self
.
__tree
=
tree
self
.
__variables
=
dict
(
variables
)
...
...
@@ -263,8 +281,44 @@ class Match(object):
@
property
@
deprecated
(
'2.6.0'
,
'3.0.0'
,
'Use template instead'
)
def
short_name
(
self
):
return
self
.
__short_name
return
self
.
template
@
property
def
template
(
self
):
return
self
.
__template
@
property
def
full_name
(
self
):
"""The ``full_name`` of a ``Match`` is a combination of the
``template`` (i.e. the matched template), and the name(s) of
the relevant ``FileTree`` objects.
It allows one to unamiguously identify the location of a ``Match``
in a ``FileTree`` hierarchy, where the same ``short_name`` may be
used in different sub-trees.
"""
def
parents
(
tree
):
if
tree
.
parent
is
None
:
return
[]
else
:
return
[
tree
.
parent
]
+
parents
(
tree
.
parent
)
trees
=
[
self
.
tree
]
+
parents
(
self
.
tree
)
# Drop the root tree
trees
=
list
(
reversed
(
trees
))[
1
:]
return
'/'
.
join
([
t
.
name
for
t
in
trees
]
+
[
self
.
template
])
@
property
def
tree
(
self
):
return
self
.
__tree
@
property
...
...
@@ -275,7 +329,8 @@ class Match(object):
def
__eq__
(
self
,
other
):
return
(
isinstance
(
other
,
Match
)
and
self
.
filename
==
other
.
filename
and
self
.
short_name
==
other
.
short_name
and
self
.
template
==
other
.
template
and
self
.
tree
is
other
.
tree
and
self
.
variables
==
other
.
variables
)
...
...
@@ -289,7 +344,7 @@ class Match(object):
def
__repr__
(
self
):
"""Returns a string representation of this ``Match``. """
return
'Match({})'
.
format
(
self
.
filename
)
return
'Match(
{}:
{})'
.
format
(
self
.
full_name
,
self
.
filename
)
def
__str__
(
self
):
...
...
@@ -301,11 +356,13 @@ def scan(tree : FileTree) -> List[Match]:
"""Scans the directory of the given ``FileTree`` to find all files which
match a tree template.
:return: list of :class:`Match` objects
:arg tree: :class:`.FileTree` to scan
:returns: list of :class:`Match` objects
"""
matches
=
[]
for
template
in
tree
.
templates
:
for
filename
in
tree
.
get_all
(
template
,
glob_vars
=
'all'
):
if
not
op
.
isfile
(
filename
):
...
...
@@ -313,7 +370,7 @@ def scan(tree : FileTree) -> List[Match]:
variables
=
dict
(
tree
.
extract_variables
(
template
,
filename
))
matches
.
append
(
Match
(
filename
,
template
,
variables
))
matches
.
append
(
Match
(
filename
,
template
,
tree
,
variables
))
for
tree_name
,
sub_tree
in
tree
.
sub_trees
.
items
():
matches
.
extend
(
scan
(
sub_tree
))
...
...
@@ -336,26 +393,25 @@ def allVariables(
variables and their possible values present in the given list
of ``Match`` objects.
- A dict of ``{ short_name : [variables] }`` mappings,
containing the variables which are relevant to each short
name.
- A dict of ``{ full_name : [variables] }`` mappings,
containing the variables which are relevant to each template.
"""
allvars
=
collections
.
defaultdict
(
set
)
all
shortnam
es
=
collections
.
defaultdict
(
set
)
allvars
=
collections
.
defaultdict
(
set
)
all
templat
es
=
collections
.
defaultdict
(
set
)
for
m
in
matches
:
for
var
,
val
in
m
.
variables
.
items
():
allvars
[
var
]
.
add
(
val
)
all
shortnames
[
m
.
short
_name
].
add
(
var
)
allvars
[
var
]
.
add
(
val
)
all
templates
[
m
.
full
_name
].
add
(
var
)
# allow us to compare None with strings
def
key
(
v
):
if
v
is
None
:
return
''
else
:
return
v
allvars
=
{
var
:
list
(
sorted
(
vals
,
key
=
key
))
for
var
,
vals
in
allvars
.
items
()}
all
shortnam
es
=
{
sn
:
list
(
sorted
(
vars
))
for
sn
,
vars
in
all
shortnam
es
.
items
()}
allvars
=
{
var
:
list
(
sorted
(
vals
,
key
=
key
))
for
var
,
vals
in
allvars
.
items
()}
all
templat
es
=
{
sn
:
list
(
sorted
(
vars
))
for
sn
,
vars
in
all
templat
es
.
items
()}
return
allvars
,
all
shortnam
es
return
allvars
,
all
templat
es
tests/test_filetree/test_query.py
View file @
287207e5
...
...
@@ -52,7 +52,7 @@ def _test_data():
yield
def
_expected_matches
(
short_nam
e
,
**
kwargs
):
def
_expected_matches
(
template
,
tre
e
,
**
kwargs
):
matches
=
[]
subjs
=
kwargs
.
get
(
'participant'
,
_subjs
)
...
...
@@ -64,18 +64,20 @@ def _expected_matches(short_name, **kwargs):
sesdir
=
op
.
join
(
'subj-{}'
.
format
(
subj
),
'ses-{}'
.
format
(
ses
))
if
short_nam
e
in
(
'T1w'
,
'T2w'
):
f
=
op
.
join
(
sesdir
,
'{}.nii.gz'
.
format
(
short_nam
e
))
if
templat
e
in
(
'T1w'
,
'T2w'
):
f
=
op
.
join
(
sesdir
,
'{}.nii.gz'
.
format
(
templat
e
))
matches
.
append
(
ftquery
.
Match
(
f
,
short_name
,
template
,
tree
,
{
'participant'
:
subj
,
'session'
:
ses
}))
elif
short_nam
e
==
'surface'
:
elif
templat
e
==
'surface'
:
for
hemi
,
surf
in
it
.
product
(
hemis
,
surfs
):
f
=
op
.
join
(
sesdir
,
'{}.{}.gii'
.
format
(
hemi
,
surf
))
matches
.
append
(
ftquery
.
Match
(
f
,
short_name
,
template
,
tree
,
{
'participant'
:
subj
,
'session'
:
ses
,
'hemi'
:
hemi
,
...
...
@@ -84,19 +86,19 @@ def _expected_matches(short_name, **kwargs):
return
matches
def
_run_and_check_query
(
query
,
short_nam
e
,
asarray
=
False
,
**
vars
):
def
_run_and_check_query
(
query
,
templat
e
,
asarray
=
False
,
**
vars
):
gotmatches
=
query
.
query
(
short_nam
e
,
asarray
=
asarray
,
**
vars
)
expmatches
=
_expected_matches
(
short_nam
e
,
**
{
k
:
[
v
]
for
k
,
v
in
vars
.
items
()})
gotmatches
=
query
.
query
(
templat
e
,
asarray
=
asarray
,
**
vars
)
expmatches
=
_expected_matches
(
template
,
query
.
tre
e
,
**
{
k
:
[
v
]
for
k
,
v
in
vars
.
items
()})
if
not
asarray
:
assert
len
(
gotmatches
)
==
len
(
expmatches
)
for
got
,
exp
in
zip
(
sorted
(
gotmatches
),
sorted
(
expmatches
)):
assert
got
==
exp
else
:
snvars
=
query
.
variables
(
short_nam
e
)
snvars
=
query
.
variables
(
templat
e
)
assert
len
(
snvars
)
==
len
(
gotmatches
.
shape
)
...
...
@@ -108,7 +110,7 @@ def _run_and_check_query(query, short_name, asarray=False, **vars):
for
expmatch
in
expmatches
:
slc
=
[]
for
var
in
query
.
axes
(
short_nam
e
):
for
var
in
query
.
axes
(
templat
e
):
if
var
not
in
vars
or
vars
[
var
]
==
'*'
:
vidx
=
snvars
[
var
].
index
(
expmatch
.
variables
[
var
])
slc
.
append
(
vidx
)
...
...
@@ -128,7 +130,7 @@ def test_query_properties():
'participant'
,
'session'
,
'surf'
]
assert
sorted
(
query
.
short_nam
es
)
==
[
'T1w'
,
'T2w'
,
'surface'
]
assert
sorted
(
query
.
templat
es
)
==
[
'T1w'
,
'T2w'
,
'surface'
]
assert
query
.
variables
(
'T1w'
)
==
{
'participant'
:
[
'01'
,
'02'
,
'03'
],
'session'
:
[
'1'
,
'2'
]}
...
...
@@ -318,7 +320,7 @@ def test_query_subtree():
tree
=
filetree
.
FileTree
.
read
(
'tree1.tree'
,
'.'
)
query
=
filetree
.
FileTreeQuery
(
tree
)
assert
sorted
(
query
.
short_nam
es
)
==
[
'T1w'
,
'surface'
]
assert
sorted
(
query
.
templat
es
)
==
[
'T1w'
,
'
surfdir/
surface'
]
qvars
=
query
.
variables
()
assert
sorted
(
qvars
.
keys
())
==
[
'hemi'
,
'participant'
,
'surf'
]
...
...
@@ -330,7 +332,7 @@ def test_query_subtree():
assert
sorted
(
qvars
.
keys
())
==
[
'participant'
]
assert
qvars
[
'participant'
]
==
[
'01'
,
'02'
,
'03'
]
qvars
=
query
.
variables
(
'surface'
)
qvars
=
query
.
variables
(
'
surfdir/
surface'
)
assert
sorted
(
qvars
.
keys
())
==
[
'hemi'
,
'participant'
,
'surf'
]
assert
qvars
[
'hemi'
]
==
[
'L'
,
'R'
]
assert
qvars
[
'participant'
]
==
[
'01'
,
'02'
,
'03'
]
...
...
@@ -346,7 +348,7 @@ def test_query_subtree():
assert
[
m
.
filename
for
m
in
sorted
(
got
)]
==
[
op
.
join
(
'subj-01'
,
'T1w.nii.gz'
)]
got
=
query
.
query
(
'surface'
)
got
=
query
.
query
(
'
surfdir/
surface'
)
assert
[
m
.
filename
for
m
in
sorted
(
got
)]
==
[
op
.
join
(
'subj-01'
,
'surf'
,
'L.pial.gii'
),
op
.
join
(
'subj-01'
,
'surf'
,
'L.white.gii'
),
...
...
@@ -361,7 +363,7 @@ def test_query_subtree():
op
.
join
(
'subj-03'
,
'surf'
,
'R.pial.gii'
),
op
.
join
(
'subj-03'
,
'surf'
,
'R.white.gii'
)]
got
=
query
.
query
(
'surface'
,
hemi
=
'L'
)
got
=
query
.
query
(
'
surfdir/
surface'
,
hemi
=
'L'
)
assert
[
m
.
filename
for
m
in
sorted
(
got
)]
==
[
op
.
join
(
'subj-01'
,
'surf'
,
'L.pial.gii'
),
op
.
join
(
'subj-01'
,
'surf'
,
'L.white.gii'
),
...
...
@@ -370,7 +372,7 @@ def test_query_subtree():
op
.
join
(
'subj-03'
,
'surf'
,
'L.pial.gii'
),
op
.
join
(
'subj-03'
,
'surf'
,
'L.white.gii'
)]
got
=
query
.
query
(
'surface'
,
surf
=
'white'
)
got
=
query
.
query
(
'
surfdir/
surface'
,
surf
=
'white'
)
assert
[
m
.
filename
for
m
in
sorted
(
got
)]
==
[
op
.
join
(
'subj-01'
,
'surf'
,
'L.white.gii'
),
op
.
join
(
'subj-01'
,
'surf'
,
'R.white.gii'
),
...
...
@@ -394,16 +396,17 @@ def test_scan():
t1wf
=
op
.
join
(
sesdir
,
'T1w.nii.gz'
)
t2wf
=
op
.
join
(
sesdir
,
'T2w.nii.gz'
)
expmatches
.
append
(
ftquery
.
Match
(
t1wf
,
'T1w'
,
{
'participant'
:
subj
,
'session'
:
ses
}))
expmatches
.
append
(
ftquery
.
Match
(
t2wf
,
'T2w'
,
{
'participant'
:
subj
,
'session'
:
ses
}))
expmatches
.
append
(
ftquery
.
Match
(
t1wf
,
'T1w'
,
tree
,
{
'participant'
:
subj
,
'session'
:
ses
}))
expmatches
.
append
(
ftquery
.
Match
(
t2wf
,
'T2w'
,
tree
,
{
'participant'
:
subj
,
'session'
:
ses
}))
for
hemi
,
surf
in
it
.
product
(
_hemis
,
_surfs
):
surff
=
op
.
join
(
sesdir
,
'{}.{}.gii'
.
format
(
hemi
,
surf
))
expmatches
.
append
(
ftquery
.
Match
(
surff
,
'surface'
,
tree
,
{
'participant'
:
subj
,
'session'
:
ses
,
'surf'
:
surf
,
...
...
@@ -414,7 +417,7 @@ def test_scan():
for
got
,
exp
in
zip
(
sorted
(
gotmatches
),
sorted
(
expmatches
)):
assert
got
.
filename
==
exp
.
filename
assert
got
.
short_name
==
exp
.
short_nam
e
assert
got
.
template
==
exp
.
templat
e
assert
got
.
variables
==
exp
.
variables
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment