Skip to content

Commit 53ae3b1

Browse files
committed
Add inverse transforms.
1 parent 1e5acc6 commit 53ae3b1

File tree

2 files changed

+52
-7
lines changed

2 files changed

+52
-7
lines changed

src/fmripost_template/data/io_spec.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,11 @@
148148
"desc": null,
149149
"suffix": "xfm",
150150
"extension": ".h5"
151+
},
152+
"all_transforms": {
153+
"mode": "image",
154+
"suffix": "xfm",
155+
"extension": [".h5", ".txt"]
151156
}
152157
}
153158
},

src/fmripost_template/utils/utils.py

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -132,37 +132,77 @@ def find_shortest_path(space_pairs, start, end):
132132

133133

134134
def get_transforms(source, target, local_transforms=None):
135-
"""Get the transforms required to go from source to target space."""
135+
"""Get the transforms required to go from source to target space.
136+
137+
Parameters
138+
----------
139+
source : str
140+
The source space.
141+
target : str
142+
The target space.
143+
local_transforms : list of str, optional
144+
List of local transforms to consider.
145+
146+
Returns
147+
-------
148+
selected_transforms : list of str
149+
List of selected transforms to go from source to target space.
150+
selected_inversions : list of bool
151+
List of booleans indicating whether the corresponding transform should be inverted.
152+
153+
Raises
154+
------
155+
ValueError
156+
If no chain of transforms can link the source and target spaces.
157+
"""
136158
import templateflow.api as tflow
137159
from bids.layout import Entity, parse_file_entities
138160

139161
query = [
140-
Entity('template', 'tpl-([a-zA-Z0-9]+)'),
141-
Entity('from', 'from-([a-zA-Z0-9]+)'),
162+
Entity('template', 'tpl-([a-zA-Z0-9+]+)'),
163+
Entity('from', 'from-([a-zA-Z0-9+]+)'),
164+
Entity('to', 'to-([a-zA-Z0-9+]+)'),
142165
]
143166

144167
all_transforms = local_transforms or []
145168

146169
templates = tflow.get_templates()
170+
tfl_transforms = []
147171
for template in templates:
148172
template_transforms = tflow.get(template, suffix='xfm', extension='h5')
149173
if not isinstance(template_transforms, list):
150174
template_transforms = [template_transforms]
151-
all_transforms += template_transforms
175+
tfl_transforms += template_transforms
152176

177+
all_transforms += tfl_transforms
153178
links = []
154179
for transform in all_transforms:
155180
entities = parse_file_entities(transform, entities=query)
156-
link = (entities['from'], entities['template'])
181+
if 'template' in entities:
182+
link = (entities['from'], entities['template'])
183+
else:
184+
link = (entities['from'], entities['to'])
157185
links.append(link)
158186

187+
inversions = [False] * len(all_transforms)
188+
189+
# Add inverses of all templateflow transforms (local transforms might not be invertible)
190+
for transform in tfl_transforms:
191+
entities = parse_file_entities(transform, entities=query)
192+
if 'template' in entities:
193+
links.append((entities['template'], entities['from']))
194+
else:
195+
links.append((entities['to'], entities['from']))
196+
inversions.append(True)
197+
159198
path = None
160199
try:
161200
path = find_shortest_path(links, source, target)
162201
print('Shortest path:', path)
163202
except ValueError as e:
164-
print(e)
203+
raise ValueError(f'Failed to find a path from {source} to {target}') from e
165204

166205
selected_transforms = [all_transforms[i] for i in path]
206+
selected_inversions = [inversions[i] for i in path]
167207

168-
return selected_transforms
208+
return selected_transforms, selected_inversions

0 commit comments

Comments
 (0)