From 844a67b8ec67831b10538e4cb3eea1d65f88e92d Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Wed, 15 Nov 2023 10:06:02 -0500 Subject: [PATCH 1/4] Add ASL to suffixes. --- sdcflows/fieldmaps.py | 4 +++- sdcflows/utils/wrangler.py | 14 +++++++++++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/sdcflows/fieldmaps.py b/sdcflows/fieldmaps.py index a9825620f3..b500037fb6 100644 --- a/sdcflows/fieldmaps.py +++ b/sdcflows/fieldmaps.py @@ -55,6 +55,8 @@ class EstimatorType(Enum): "bold": EstimatorType.PEPOLAR, "dwi": EstimatorType.PEPOLAR, "epi": EstimatorType.PEPOLAR, + "asl": EstimatorType.PEPOLAR, + "m0scan": EstimatorType.PEPOLAR, "fieldmap": EstimatorType.MAPPED, "magnitude": None, "magnitude1": None, @@ -370,7 +372,7 @@ def __attrs_post_init__(self): # Fieldmap option 2: PEPOLAR (and fieldmap-less or ANAT) # IMPORTANT NOTE: fieldmap-less approaches can be considered PEPOLAR with RO = 0.0s - pepolar_types = suffix_set.intersection(("bold", "dwi", "epi", "sbref")) + pepolar_types = suffix_set.intersection(("bold", "dwi", "epi", "sbref", "asl", "m0scan")) anat_types = suffix_set.intersection(("T1w", "T2w")) _pepolar_estimation = ( len([f for f in suffix_list if f in ("bold", "dwi", "epi", "sbref")]) > 1 diff --git a/sdcflows/utils/wrangler.py b/sdcflows/utils/wrangler.py index 4ec346b372..8f964cabe8 100644 --- a/sdcflows/utils/wrangler.py +++ b/sdcflows/utils/wrangler.py @@ -305,7 +305,7 @@ def find_estimators( sessions = sessions or layout.get_sessions(subject=subject) or [None] fmapless = fmapless or {} if fmapless is True: - fmapless = {"bold", "dwi"} + fmapless = {"bold", "dwi", "asl"} estimators = [] @@ -442,7 +442,7 @@ def find_estimators( intent_map = [] for sbref in sbrefs: ents = sbref.get_entities(metadata=False) - ents["suffix"] = ["bold", "dwi"] + ents["suffix"] = ["bold", "dwi", "asl"] intent_map.append( [ target @@ -483,6 +483,7 @@ def find_estimators( estimators.append(e) if estimators and not force_fmapless: + logger.warning(f"Estimators found: {estimators}") fmapless = False # Find fieldmap-less schemes @@ -502,6 +503,7 @@ def find_estimators( suffixes=fmapless, ) for spec in estimator_specs: + logger.warning(f"Estimator spec: {spec}") try: estimator = fm.FieldmapEstimation(spec) except (ValueError, TypeError) as err: @@ -509,6 +511,7 @@ def find_estimators( else: _log_debug_estimation(logger, estimator, layout.root) estimators.append(estimator) + return estimators @@ -542,8 +545,10 @@ def find_anatomical_estimators( EPI suffixes, for example ``["bold", "dwi"]``. Associated ``"sbref"``\s will be found and used in place of BOLD/diffusion EPIs. """ - from .epimanip import get_trt + from .misc import create_logger + + logger = create_logger('sdcflows.wrangler2') subject_root = Path(layout.root) / f"sub-{subject}" @@ -554,6 +559,7 @@ def find_anatomical_estimators( datatype = { "bold": "func", "dwi": "dwi", + "asl": "perf", }[suffix] candidates = layout.get( **{ @@ -561,6 +567,7 @@ def find_anatomical_estimators( **{"suffix": suffixes, "session": ses, "datatype": datatype}, } ) + logger.warning(f"Candidates: {candidates}") # Filter out candidates without defined PE direction epi_targets = [] @@ -569,6 +576,7 @@ def find_anatomical_estimators( meta = candidate.get_metadata() if not meta.get("PhaseEncodingDirection"): + logger.warning(f"PhaseEncodingDirection missing in meta: {meta}") continue trt = 1.0 From e21319eccd414a1035461ee16781cf57a03fc223 Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Fri, 1 Dec 2023 10:21:18 -0500 Subject: [PATCH 2/4] Add ASL and M0 scan in other locations. --- sdcflows/fieldmaps.py | 4 ++-- sdcflows/utils/wrangler.py | 19 ++++++------------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/sdcflows/fieldmaps.py b/sdcflows/fieldmaps.py index b500037fb6..5a2e27bed6 100644 --- a/sdcflows/fieldmaps.py +++ b/sdcflows/fieldmaps.py @@ -243,7 +243,7 @@ def __attrs_post_init__(self): self.metadata["TotalReadoutTime"] = 0.0 # Check for REQUIRED metadata (depends on suffix.) - if self.suffix in ("bold", "dwi", "epi", "sbref"): + if self.suffix in ("bold", "dwi", "epi", "sbref", "asl", "m0scan"): if "PhaseEncodingDirection" not in self.metadata: raise MetadataError( f"Missing 'PhaseEncodingDirection' for <{self.path}>." @@ -375,7 +375,7 @@ def __attrs_post_init__(self): pepolar_types = suffix_set.intersection(("bold", "dwi", "epi", "sbref", "asl", "m0scan")) anat_types = suffix_set.intersection(("T1w", "T2w")) _pepolar_estimation = ( - len([f for f in suffix_list if f in ("bold", "dwi", "epi", "sbref")]) > 1 + len([f for f in suffix_list if f in ("bold", "dwi", "epi", "sbref", "asl", "m0scan")]) > 1 ) if _pepolar_estimation and not anat_types: diff --git a/sdcflows/utils/wrangler.py b/sdcflows/utils/wrangler.py index 4c5b956f00..65e0643252 100644 --- a/sdcflows/utils/wrangler.py +++ b/sdcflows/utils/wrangler.py @@ -63,9 +63,9 @@ def find_estimators( One of more session identifiers. If None, all sessions will be used. fmapless : :obj:`bool` or :obj:`set` Indicates if fieldmap-less heuristics should be executed. - When ``fmapless`` is a :obj:`set`, it can contain valid BIDS suffices - for EPI images (namely, ``"dwi"``, ``"bold"``, or ``"sbref"``). - When ``fmapless`` is ``True``, heuristics will use the ``{"bold", "dwi"}`` set. + When ``fmapless`` is a :obj:`set`, it can contain valid BIDS suffixes + for EPI images (namely, ``"dwi"``, ``"bold"``, ``"asl"``, or ``"sbref"``). + When ``fmapless`` is ``True``, heuristics will use the ``{"bold", "dwi", "asl"}`` set. force_fmapless : :obj:`bool` When some other fieldmap estimation methods have been found, fieldmap-less estimation will be skipped except if ``force_fmapless`` is ``True``. @@ -434,7 +434,7 @@ def find_estimators( all_targets.append(target) # If sbrefs are targets, then the goal is generally to estimate with epi+sbref - # and correct bold/dwi + # and correct bold/dwi/asl sbrefs = [ target for target in all_targets if target.entities["suffix"] == "sbref" ] @@ -484,7 +484,6 @@ def find_estimators( estimators.append(e) if estimators and not force_fmapless: - logger.warning(f"Estimators found: {estimators}") fmapless = False # Find fieldmap-less schemes @@ -504,7 +503,6 @@ def find_estimators( suffixes=fmapless, ) for spec in estimator_specs: - logger.warning(f"Estimator spec: {spec}") try: estimator = fm.FieldmapEstimation(spec) except (ValueError, TypeError) as err: @@ -512,7 +510,6 @@ def find_estimators( else: _log_debug_estimation(logger, estimator, layout.root) estimators.append(estimator) - return estimators @@ -543,13 +540,11 @@ def find_anatomical_estimators( base_entities : :class:`dict` Entities to use to query for images. These should include any filters. suffixes : :class:`list` - EPI suffixes, for example ``["bold", "dwi"]``. Associated ``"sbref"``\s + EPI suffixes, for example ``["bold", "dwi", "asl"]``. Associated ``"sbref"``\s will be found and used in place of BOLD/diffusion EPIs. """ - from .epimanip import get_trt - from .misc import create_logger - logger = create_logger('sdcflows.wrangler2') + from .epimanip import get_trt subject_root = Path(layout.root) / f"sub-{subject}" @@ -568,7 +563,6 @@ def find_anatomical_estimators( **{"suffix": suffixes, "session": ses, "datatype": datatype}, } ) - logger.warning(f"Candidates: {candidates}") # Filter out candidates without defined PE direction epi_targets = [] @@ -577,7 +571,6 @@ def find_anatomical_estimators( meta = candidate.get_metadata() if not meta.get("PhaseEncodingDirection"): - logger.warning(f"PhaseEncodingDirection missing in meta: {meta}") continue trt = 1.0 From 6c678d557b8eb552ffffb4797e552d8755e397c6 Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Fri, 1 Dec 2023 10:25:03 -0500 Subject: [PATCH 3/4] Address style issue. --- sdcflows/fieldmaps.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sdcflows/fieldmaps.py b/sdcflows/fieldmaps.py index 5a2e27bed6..c1e1d3eeb9 100644 --- a/sdcflows/fieldmaps.py +++ b/sdcflows/fieldmaps.py @@ -375,7 +375,9 @@ def __attrs_post_init__(self): pepolar_types = suffix_set.intersection(("bold", "dwi", "epi", "sbref", "asl", "m0scan")) anat_types = suffix_set.intersection(("T1w", "T2w")) _pepolar_estimation = ( - len([f for f in suffix_list if f in ("bold", "dwi", "epi", "sbref", "asl", "m0scan")]) > 1 + len( + [f for f in suffix_list if f in ("bold", "dwi", "epi", "sbref", "asl", "m0scan")] + ) > 1 ) if _pepolar_estimation and not anat_types: From 3ef588a50a24226d44dcd14e5aa5a7c81bce5795 Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Mon, 4 Dec 2023 10:22:17 -0500 Subject: [PATCH 4/4] Update sdcflows/utils/wrangler.py Co-authored-by: Oscar Esteban --- sdcflows/utils/wrangler.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sdcflows/utils/wrangler.py b/sdcflows/utils/wrangler.py index 65e0643252..f046642777 100644 --- a/sdcflows/utils/wrangler.py +++ b/sdcflows/utils/wrangler.py @@ -542,6 +542,8 @@ def find_anatomical_estimators( suffixes : :class:`list` EPI suffixes, for example ``["bold", "dwi", "asl"]``. Associated ``"sbref"``\s will be found and used in place of BOLD/diffusion EPIs. + Similarly, ``"m0scan"``\s associated with ASL runs with the ``IntendedFor`` or + ``B0FieldIdentifier`` metadata will be used in place of ASL runs. """ from .epimanip import get_trt