Skip to content

Commit

Permalink
ENH: Find B0FieldIdentifiers when one image contributes to multiple (#…
Browse files Browse the repository at this point in the history
…298)

* fix/hacks for pepolar scheme with B0FieldIdentifier as lists

* fix if no B0FieldIdentifier, empty list, (testing)

* Update sdcflows/fieldmaps.py

Co-authored-by: Chris Markiewicz <[email protected]>

* Update sdcflows/fieldmaps.py

Co-authored-by: Chris Markiewicz <[email protected]>

* Update sdcflows/fieldmaps.py

Co-authored-by: Chris Markiewicz <[email protected]>

* FIX: Update logic for finding b0 fields

* FIX: Break layout.get calls into separate lines, use repr for match instead of custom wrapping

* FIX: A more perfect union

* FIX: JSON, not repr

Co-authored-by: Chris Markiewicz <[email protected]>
  • Loading branch information
bpinsard and effigies authored Dec 6, 2022
1 parent 7898fac commit 82e7593
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 22 deletions.
44 changes: 24 additions & 20 deletions sdcflows/fieldmaps.py
Original file line number Diff line number Diff line change
Expand Up @@ -404,27 +404,31 @@ def __attrs_post_init__(self):
# Register this estimation method
if not self.bids_id:
# If not manually set, try to get it from BIDS metadata
bids_ids = set(
[
f.metadata.get("B0FieldIdentifier")
for f in self.sources
if f.metadata.get("B0FieldIdentifier")
]
)
if len(bids_ids) > 1:
raise ValueError(
f"Multiple ``B0FieldIdentifier`` set: <{', '.join(bids_ids)}>"
)
elif bids_ids:
b0_ids = [
listify(f.metadata.get("B0FieldIdentifier"))
for f in self.sources
if f.metadata.get("B0FieldIdentifier")
]

if b0_ids:
# Find common IDs
bids_ids = set(b0_ids[0]).intersection(*b0_ids[1:])
if not bids_ids:
raise ValueError(
f"No common ``B0FieldIdentifier`` found: <{', '.join(map(str, b0_ids))}>"
)
elif len(bids_ids) > 1:
raise ValueError(
f"Multiple common ``B0FieldIdentifier``s found: <{', '.join(bids_ids)}>"
)
object.__setattr__(self, "bids_id", bids_ids.pop())
else:
bids_id = _estimators.add(self.paths())
object.__setattr__(self, "bids_id", bids_id)
for intent_file in intents_meta:
_intents[intent_file].add(bids_id)
return

_estimators[self.bids_id] = self.paths()

if self.bids_id:
_estimators[self.bids_id] = self.paths()
else:
bids_id = _estimators.add(self.paths())
object.__setattr__(self, "bids_id", bids_id)

for intent_file in intents_meta:
_intents[intent_file].add(self.bids_id)

Expand Down
16 changes: 14 additions & 2 deletions sdcflows/utils/wrangler.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#
"""Find fieldmaps on the BIDS inputs for :abbr:`SDC (susceptibility distortion correction)`."""
import logging
from functools import reduce
from itertools import product
from contextlib import suppress
from pathlib import Path
Expand Down Expand Up @@ -293,7 +294,12 @@ def find_estimators(
# Step 1. Use B0FieldIdentifier metadata
b0_ids = tuple()
with suppress(BIDSEntityError):
b0_ids = layout.get_B0FieldIdentifiers(**base_entities)
# flatten lists from json (tupled in pybids for hashing), then unique
b0_ids = reduce(
set.union,
(listify(ids) for ids in layout.get_B0FieldIdentifiers(**base_entities)),
set()
)

if b0_ids:
logger.debug(
Expand All @@ -305,9 +311,15 @@ def find_estimators(
b0_entities = base_entities.copy()
b0_entities["B0FieldIdentifier"] = b0_id

bare_ids = layout.get(**base_entities, B0FieldIdentifier=b0_id)
listed_ids = layout.get(
**base_entities,
B0FieldIdentifier=f'"{b0_id}"', # Double quotes to match JSON, not Python repr
regex_search=True,
)
e = fm.FieldmapEstimation([
fm.FieldmapFile(fmap.path, metadata=fmap.get_metadata())
for fmap in layout.get(**b0_entities)
for fmap in bare_ids + listed_ids
])
_log_debug_estimation(logger, e, layout.root)
estimators.append(e)
Expand Down

0 comments on commit 82e7593

Please sign in to comment.