Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add quick utils functions to get B and C matrices from off-resonance maps #124

Closed
1 of 4 tasks
chaithyagr opened this issue Jun 4, 2024 · 3 comments · Fixed by #180
Closed
1 of 4 tasks

Add quick utils functions to get B and C matrices from off-resonance maps #124

chaithyagr opened this issue Jun 4, 2024 · 3 comments · Fixed by #180
Assignees
Labels
feature request New feature or request

Comments

@chaithyagr
Copy link
Member

chaithyagr commented Jun 4, 2024

Currently, in

class MRIFourierCorrected(FourierOperatorBase):
"""Fourier Operator with B0 Inhomogeneities compensation.
This is a wrapper around the Fourier Operator to compensate for the
B0 inhomogeneities in the k-space.
Parameters
----------
fourier_op: object of class FourierBase
the fourier operator to wrap
B: numpy.ndarray
C: numpy.ndarray
indices: numpy.ndarray
backend: str, default 'cpu'
the backend to use for computations. Either 'cpu' or 'gpu'.
"""
def __init__(self, fourier_op, B, C, indices, backend="cpu"):
if backend == "gpu" and not CUPY_AVAILABLE:
raise RuntimeError("Cupy is required for gpu computations.")
if backend == "gpu":
self.xp = cp
elif backend == "cpu":
self.xp = np
else:
raise ValueError("Unsupported backend.")
self._fourier_op = fourier_op
if not fourier_op.uses_sense:
raise ValueError("please use smaps.")
self.n_samples = fourier_op.n_samples
self.n_coils = fourier_op.n_coils
self.shape = fourier_op.shape
self.smaps = fourier_op.smaps
self.n_interpolators = len(C)
self.B = self.xp.array(B)
self.B = self.xp.tile(self.B, (self._fourier_op.n_samples // len(B), 1))
self.C = self.xp.array(C)
self.indices = indices

we just generate the fourier_op which takes the B and C values into account.

  • It might help to also include a function in mrinufft.operators.off_resonance called get_interpolators_from_fieldmap.
  • Also, it might further help to be able to get fourier correction possible directly from the init function itself like MRIFourierCorrected(fourier_op, b0_field, mask)
  • It could be useful to allow for autodiff to pass through this new fourier op, currently we only support cupy or numpy, it might help to check if we have autograd enabled on based fourier_op and enable it as well (we just need to have tensors as torch tensors.
  • A bit distant, but it could help to have the off-resonance estimation from k-space data as function. Although, this is a bit distant and I really feel it should belong to pysap-mri.
@paquiteau
Copy link
Member

I fully agree with you.

Getting the off resonance map from the k space data could be done in the extras module, just as we propose it for the smaps estimation.

We may also wish to have autodiff support around this as well ?

@chaithyagr
Copy link
Member Author

Sure. But note that the estimation isnt trivial, it is computationally expensive (for now). @Daval-G you think these codes can be open sourced though? I wanted to confirm that.

@philouc
Copy link
Collaborator

philouc commented Jun 5, 2024

I agree with @paquiteau : Estimation of off-resonance effects from k-space data should be carried out separately, as it depends on the phase information usually extracted from the image domain and TE value.

@paquiteau paquiteau added the feature request New feature or request label Jun 5, 2024
mcencini added a commit to mcencini/mri-nufft that referenced this issue Aug 8, 2024
This add "get_interpolators_from_fieldmap", supporting both real (B0 map only) and complex (Zmap = R2* + 1j * B0map) fields
in arbitrary dimension (2D and 3D). The routine supports both numpy / cupy arrays and torch tensors on CPU and GPU,
the latter requiring cupy due to limitations in torch.histogram / torch.histogramdd (pytorch/pytorch#69519).

Calculation uses time segmentation with uniform time samples and LS coefficients (using histogram).

Based on MIRT (https://github.com/JeffFessler/mirt/blob/main/mri/mri_exp_approx.m)
and its Python porting from MIRTORCH (https://github.com/guanhuaw/MIRTorch/blob/master/mirtorch/linear/mri.py)
and SigPy (https://github.com/mikgroup/sigpy/blob/main/sigpy/mri/util.py).
@paquiteau paquiteau linked a pull request Aug 9, 2024 that will close this issue
paquiteau pushed a commit that referenced this issue Sep 17, 2024
* fix typoes (off_resonnance -> off_resonance)

* feat: add field interpolators calculation (#124)

This add "get_interpolators_from_fieldmap", supporting both real (B0 map only) and complex (Zmap = R2* + 1j * B0map) fields
in arbitrary dimension (2D and 3D). The routine supports both numpy / cupy arrays and torch tensors on CPU and GPU,
the latter requiring cupy due to limitations in torch.histogram / torch.histogramdd (pytorch/pytorch#69519).

Calculation uses time segmentation with uniform time samples and LS coefficients (using histogram).

Based on MIRT (https://github.com/JeffFessler/mirt/blob/main/mri/mri_exp_approx.m)
and its Python porting from MIRTORCH (https://github.com/guanhuaw/MIRTorch/blob/master/mirtorch/linear/mri.py)
and SigPy (https://github.com/mikgroup/sigpy/blob/main/sigpy/mri/util.py).

* feat: field interpolator estimation in MRIFourierCorrected constructor.

In addition, add off-resonance example.

* feat: set autograd_available based on base FourierOperator

* Update test_offres_exp_approx.py

Avoid torch cuda test case if cupy is not available.

* Update src/mrinufft/operators/off_resonance.py

remove deprecated get_grad

Co-authored-by: Chaithya G R <[email protected]>

* address pr review

* remove phantominator

* remove duplicated example and replacing subject in example_offres

* address PR rev #2

* \!docs_build and fix on \!style

* \!docs_build

* skip field coefficient gpu test case if cupy not available

* \!docs_build fix gpuNUFFT

* Update src/mrinufft/operators/off_resonance.py

Co-authored-by: Guillaume Daval-Frérot <[email protected]>

* Update src/mrinufft/operators/off_resonance.py

Co-authored-by: Guillaume Daval-Frérot <[email protected]>

* \!docs_build gpunufft

* Update src/mrinufft/operators/off_resonance.py

Co-authored-by: Guillaume Daval-Frérot <[email protected]>

* Update src/mrinufft/operators/off_resonance.py

Co-authored-by: Guillaume Daval-Frérot <[email protected]>

* address PR rev 3

* Update pyproject.toml

* Update src/mrinufft/operators/off_resonance.py

Co-authored-by: Guillaume Daval-Frérot <[email protected]>

* \![docs_build]

* temp, \![docs_build] fix

* fix cufinufft, \!docs_build fix

---------

Co-authored-by: Chaithya G R <[email protected]>
Co-authored-by: Guillaume Daval-Frérot <[email protected]>
paquiteau added a commit that referenced this issue Sep 30, 2024
* fix typoes (off_resonnance -> off_resonance)

* feat: add field interpolators calculation (#124)

This add "get_interpolators_from_fieldmap", supporting both real (B0 map only) and complex (Zmap = R2* + 1j * B0map) fields
in arbitrary dimension (2D and 3D). The routine supports both numpy / cupy arrays and torch tensors on CPU and GPU,
the latter requiring cupy due to limitations in torch.histogram / torch.histogramdd (pytorch/pytorch#69519).

Calculation uses time segmentation with uniform time samples and LS coefficients (using histogram).

Based on MIRT (https://github.com/JeffFessler/mirt/blob/main/mri/mri_exp_approx.m)
and its Python porting from MIRTORCH (https://github.com/guanhuaw/MIRTorch/blob/master/mirtorch/linear/mri.py)
and SigPy (https://github.com/mikgroup/sigpy/blob/main/sigpy/mri/util.py).

* feat: field interpolator estimation in MRIFourierCorrected constructor.

In addition, add off-resonance example.

* feat: set autograd_available based on base FourierOperator

* Update test_offres_exp_approx.py

Avoid torch cuda test case if cupy is not available.

* Update src/mrinufft/operators/off_resonance.py

remove deprecated get_grad

Co-authored-by: Chaithya G R <[email protected]>

* address pr review

* remove phantominator

* remove duplicated example and replacing subject in example_offres

* address PR rev #2

* \!docs_build and fix on \!style

* \!docs_build

* enhancement: refactor with_* decorator to support standalone functions.

* skip field coefficient gpu test case if cupy not available

* \!docs_build fix gpuNUFFT

* Update src/mrinufft/operators/off_resonance.py

Co-authored-by: Guillaume Daval-Frérot <[email protected]>

* Update src/mrinufft/operators/off_resonance.py

Co-authored-by: Guillaume Daval-Frérot <[email protected]>

* \!docs_build gpunufft

* Update src/mrinufft/operators/off_resonance.py

Co-authored-by: Guillaume Daval-Frérot <[email protected]>

* Update src/mrinufft/operators/off_resonance.py

Co-authored-by: Guillaume Daval-Frérot <[email protected]>

* address PR rev 3

* sync with off_resonance PR rev

* feat: handle kwargs only input.

* fix: decorators now working if required_grad is True

* sync with master

* Update src/mrinufft/operators/base.py

Co-authored-by: Pierre-Antoine Comby <[email protected]>

* refactor: array interface conversion in separate module.

* lint tfnufft

* remove print statements

* Update src/mrinufft/_array_compat.py

Co-authored-by: Pierre-Antoine Comby <[email protected]>

* Update src/mrinufft/_array_compat.py

Co-authored-by: Pierre-Antoine Comby <[email protected]>

* Update src/mrinufft/_array_compat.py

Co-authored-by: Pierre-Antoine Comby <[email protected]>

* enhance: handle kwargs and (nested) tuple/lists of arraylike arguments.

* update base.py

* Update src/mrinufft/_array_compat.py

Co-authored-by: Pierre-Antoine Comby <[email protected]>

* apply suggested refactor to each decorator.

---------

Co-authored-by: Chaithya G R <[email protected]>
Co-authored-by: Guillaume Daval-Frérot <[email protected]>
Co-authored-by: Pierre-Antoine Comby <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants