Skip to content

Revamp PWI4D behavior #997

@HenkMutsaerts

Description

@HenkMutsaerts

Description

WHY do we want to revamp/simplify/standardize the PWI4D behavior:

  1. Reduction of if-statements, also with a single-PLD sequence, we use as much multi-PLD code that can be used for single-PLD as well (though superfluous as nPLD=1). This makes the code easier to bugfix and test.
  2. Better performance with BASIL if we give the full PWI4D as input instead of PWI (see also PWI4D for BASIL #920)
  3. For temporal calculations, e.g. spatial CoV or proximal-distance ratio for each control-pair in the case of 2D EPI, which could be a new "temporal cerebrovascular stability" biomarker of autoregulation
    (See also Expand functionality of xASL_wrp_GetROIStatistics to 4D/temporal #594)
  4. For QCing. New QC NIfTIs/images/values needed are in Multi-PLD multi-TE QC images #1317.

DISADVANTAGE:

  1. Disk space usage increased (temporarily, could delete this intermediate NIfTI using the parameter bSavePWI4D)
  2. RAM usage increased

SUGGESTION:
ASL4D = rawdata asl.nii, time decoded
PWI4D.nii = ASL4D subtracted, so N=0.5*nVolumes
PWI3D.nii is the PLD & TE-wise averaging of PWI4D
PWI is the single PWI volume (as it was)

Requirements

Create new function xASL_im_ASLSubtractionAveraging

This is used by the following functions:

  • xASL_wrp_RealignASL uses mean PWI to create a mask for ENABLE
  • xASL_wrp_RegisterASL uses this to create single PWI for registration purposes
  • xASL_wrp_ResampleASL uses this to save PWI4D PWI3D PWI, etc
  • xASL_quant_ASL uses this to create the PWI from the last PWI4D image
  • Normalize ASL4D -> PWI4D -> PWI3D -> PWI for all multi-PLD, multi-TE, multi-LD sequences
  • move xASL_wrp_Resample section 8 subtraction & averaging to xASL_im_ASLSubtractionAveraging
  • Equalized handling quantification parameters, e.g., x.Q.EchoTime -> x.Q.EchoTime_PWI4D -> x.Q.EchoTime_PWI3D -> x.Q.EchoTime_PWI
  • Add motion application (spm_reslice) before resampling (based on existence of .mat sidecar)

Other

  • x.EchoTime -> x.Q.EchoTime
  • Handling x.Q.EchoTime x.Q.Initial_PLD x.Q.LabelingDuration at beginning xASL_module_ASL
  • [xASL_io_PairwiseSubtraction: add comparable interpolation to spm_reslice, for testing
  • xASL_wrp_Resample: write JSON sidecars for PWI4D.nii PWI3D.nii PWI.nii

Done HENK

Quantification

  • Change xASL_wrp_Quantify & xASL_quant_ASL accordingly (single-PLD, multi-PLD, multi-TE)
  • Also in xASL_wrp_Quantify (and its functions) equalize behavior for all sequences, e.g., always average over repeats (even if there are no repeats, this will work)

Finalize xASL_wrp_Resample

  • xASL_wrp_Resample: Move Hadamard decoding to before step 6 xASL_quant_GetMeanControl
  • Change xASL_wrp_ResampleASL -> xASL_quant_GetMeanControl accordingly?
  • Control order & PWI order may not be the same
    ASL4D -> PWI4D -> PWI3D -> PWI is separated from ASL4D -> Control4D -> Control3D -> Control
    Same for both image matrices & JSON
    So my reasoning is this:
    A. xASL_module_ASL parses the TE/PLD/LD vectors as the length of the volumes, so we are oblivious of control and label.
    B—D: xASL_im_ASLSubtractionAveraging edited in ea43014
    B. ASL4D -> PWI4D (& Control4D)
    (full TE/PLD/LD vectors come from xASL_module_ASL)
    a. if this is a simple subtraction, then for both PWI4D & Control4D, we take all odd (or even) elements from the
    TE/PLD/LD vectors
    b. if this is time encoded, then xASL_quant_HadamardDecoding will provide the new TE/PLD/LD vectors for both
    PWI4D and Control4D
    c. if we have any other structure that doesn't fit (a) or (b), we have to revamp a lot of code anyway.
    So, I propose that we keep the current code for Control4D.
    C. PWI4D & Control4D -> PWI3D & Control3D
    (TE/PLD/LD vectors come from (the stored .JSON by | directly) xASL_quant_HadamardDecoding)
    a. this is a simple averaging for all cases per unique TE-PLD-LD combination, so we average all TE/PLD/LD vectors
    as well (note the vectors may not be unique, e.g. for TE we use uniquetol, hence the averaging rather than
    taking the first only)
    D. PWI -> follows current discussion
  • If x.modules.asl.bMultiTE==false -> use first echo only in quantification etc (e.g., in the case of dual-echo
    ASL) so if numel(x.Q.EchoTimeUnique)>1 -> warning and take the first. Also state that there is no support for
    mixed ASL & fMRI (aka dual-echo ASL).
    Done in c5dc612
  • generate SD SNR wsCV NIfTIs from latest PLD — temporary fix

HENK testing done

  • Try if all cases give the same as the old code (for realign & register, for single-PLD, multi-PLD, multi-TE)

  • Fix Jan's comments

  • Allow Control4D as input with xASL_im_ASLSubtractionAveraging

  • Manage bContainsDeltaM into account

  • if bDELETETEMP: remove PWI4D at the end of xASL_wrp_Quantify

  • if SaveCBF4D -> this means disabling the averaging of CBF:
    (check if we do this already ourselves, and if we can set this for BASIL/FABBER)
    This might be a follow-up issue.
    Check Anouk's use case.

  • Test a dual-echo sequence with x.modules.asl.bMultiTE==false

  • When motion correction removes volumes with high motion, this affects ASL4D (called despiked_ASL4D) but not the parameter vectors; this needs to be fixed accordingly

  • Check if there are other instances where (despiked_)ASL4D is used, which should be replaced by PWI4D, e.g., in QC

ToDo JAN - I will clean all bugs and do these in the end

  • xASL_quant_HadamardDecoding to decode x.Q.EchoTime x.Q.Initial_PLD x.Q.LabelingDuration
    Note that Hadamard/Walsh decoding should be oblivious about the readout, it deals with the labeling strategy
    only. So, e.g., it should be oblivious for TE.
  • Hadamard decode might produce a 4D control image with multiple TEs - we need to use a 3D control for calibration then. Moved to PWI4D & session concatenation follow-up #1543
  • Separate de-interleaving (without any Hadamard parameters) and Hadamard Decoding (without any interleaving parameters).
  • Fix Unittest-32 UnitTest.tests(9).testname = 'DRO 2.3.0 (Full pipeline, rawdata->defacing->results)';

Release notes

Creating a single function for control-label subtraction for all sequence types.
Note that this branch was merged through #1551 and not directly to develop.

Metadata

Metadata

Assignees

Labels

optimizationEnsure that code runs faster with unchanged functionality

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions