{"id":15418900,"url":"https://github.com/mmuckley/torchkbnufft","last_synced_at":"2025-10-11T08:31:11.345Z","repository":{"id":36045941,"uuid":"221005701","full_name":"mmuckley/torchkbnufft","owner":"mmuckley","description":"A high-level, easy-to-deploy non-uniform Fast Fourier Transform in PyTorch.","archived":false,"fork":false,"pushed_at":"2024-12-04T15:02:28.000Z","size":14909,"stargazers_count":221,"open_issues_count":10,"forks_count":46,"subscribers_count":8,"default_branch":"main","last_synced_at":"2025-01-04T23:33:28.202Z","etag":null,"topics":["deep-learning","mri","nufft","pytorch","reconstruction"],"latest_commit_sha":null,"homepage":"https://torchkbnufft.readthedocs.io/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mmuckley.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-11-11T15:01:08.000Z","updated_at":"2025-01-02T22:04:40.000Z","dependencies_parsed_at":"2024-12-04T15:25:00.600Z","dependency_job_id":"7c858534-b68c-4aa3-a84d-4be69607983d","html_url":"https://github.com/mmuckley/torchkbnufft","commit_stats":{"total_commits":111,"total_committers":7,"mean_commits":"15.857142857142858","dds":"0.12612612612612617","last_synced_commit":"7039bc1c2d32cf86c8f25d39bcf1bf394368bdd4"},"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mmuckley%2Ftorchkbnufft","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mmuckley%2Ftorchkbnufft/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mmuckley%2Ftorchkbnufft/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mmuckley%2Ftorchkbnufft/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mmuckley","download_url":"https://codeload.github.com/mmuckley/torchkbnufft/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":236067875,"owners_count":19089802,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["deep-learning","mri","nufft","pytorch","reconstruction"],"created_at":"2024-10-01T17:23:13.205Z","updated_at":"2025-10-11T08:31:03.089Z","avatar_url":"https://github.com/mmuckley.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# torchkbnufft\n\n[![LICENSE](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n![CI Badge](https://github.com/mmuckley/torchkbnufft/workflows/Build%20and%20test/badge.svg?branch=master) [![Documentation Status](https://readthedocs.org/projects/torchkbnufft/badge/?version=stable)](https://torchkbnufft.readthedocs.io/en/stable/?badge=latest) [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/mmuckley/torchkbnufft/blob/main/notebooks/Basic%20Example.ipynb)\n\n[Documentation](https://torchkbnufft.readthedocs.io) | [GitHub](https://github.com/mmuckley/torchkbnufft) | [Notebook Examples](#examples)\n\nSimple installation from PyPI:\n\n```bash\npip install torchkbnufft\n```\n\n## About\n\n`torchkbnufft` implements a non-uniform Fast Fourier Transform\n[[1, 2](#references)] with Kaiser-Bessel gridding in PyTorch. The\nimplementation is completely in Python, facilitating flexible deployment in\nreadable code with no compilation. NUFFT functions are each wrapped as a\n```torch.autograd.Function```, allowing backpropagation through NUFFT operators\nfor training neural networks.\n\nThis package was inspired in large part by the NUFFT implementation in the\n[Michigan Image Reconstruction Toolbox (Matlab)](https://github.com/JeffFessler/mirt).\n\n### Operation Modes and Stages\n\nThe package has three major classes of NUFFT operation mode: table-based NUFFT\ninterpolation, sparse matrix-based NUFFT interpolation, and forward/backward\noperators with Toeplitz-embedded FFTs [[3](#references)]. Roughly, computation\nspeed follows:\n\n| Type          | Speed                  |\n| ------------- | ---------------------- |\n| Toeplitz      | Fastest                |\n| Table         | Medium                 |\n| Sparse Matrix | Slow (not recommended) |\n\nIt is generally best to start with Table interpolation and then experiment with\nthe other modes for your problem.\n\nSensitivity maps can be incorporated by passing them into a `KbNufft` or\n`KbNufftAdjoint` object.\n\n## Documentation\n\nAn html-based documentation reference on\n[Read the Docs](https://torchkbnufft.readthedocs.io).\n\nMost files are accompanied with docstrings that can be read with ```help```\nwhile running IPython. Example:\n\n```python\nfrom torchkbnufft import KbNufft\n\nhelp(KbNufft)\n```\n\n## Examples\n\n`torchkbnufft` can be used for N-D NUFFT transformations. The examples here\nstart with a simple 2D NUFFT, then expand it to SENSE (a task with multiple,\nparallel 2D NUFFTs).\n\nThe last two examples demonstrate NUFFTs based on sparse matrix multiplications\n(which can be useful for high-dimensional cases) and Toeplitz NUFFTs (which are\nan extremely fast forward-backward NUFFT technique).\n\nAll examples have associated notebooks that you can run in Google Colab:\n\n- [Basic Example in Colab](https://colab.research.google.com/github/mmuckley/torchkbnufft/blob/main/notebooks/Basic%20Example.ipynb)\n- [SENSE-NUFFT Example in Colab](https://colab.research.google.com/github/mmuckley/torchkbnufft/blob/main/notebooks/SENSE%20Example.ipynb)\n- [Sparse Matrix Example in Colab](https://colab.research.google.com/github/mmuckley/torchkbnufft/blob/main/notebooks/Sparse%20Matrix%20Example.ipynb)\n- [Toeplitz Example in Colab](https://colab.research.google.com/github/mmuckley/torchkbnufft/blob/main/notebooks/Toeplitz%20Example.ipynb)\n\n### Simple Forward NUFFT\n\n[Basic NUFFT Example in Colab](https://colab.research.google.com/github/mmuckley/torchkbnufft/blob/main/notebooks/Basic%20Example.ipynb)\n\nThe following code loads a Shepp-Logan phantom and computes a single radial\nspoke of k-space data:\n\n```python\nimport torch\nimport torchkbnufft as tkbn\nimport numpy as np\nfrom skimage.data import shepp_logan_phantom\n\nx = shepp_logan_phantom().astype(complex)\nim_size = x.shape\n# convert to tensor, unsqueeze batch and coil dimension\n# output size: (1, 1, ny, nx)\nx = torch.tensor(x).unsqueeze(0).unsqueeze(0).to(torch.complex64)\n\nklength = 64\nktraj = np.stack(\n    (np.zeros(64), np.linspace(-np.pi, np.pi, klength))\n)\n# convert to tensor, unsqueeze batch dimension\n# output size: (2, klength)\nktraj = torch.tensor(ktraj, dtype=torch.float)\n\nnufft_ob = tkbn.KbNufft(im_size=im_size)\n# outputs a (1, 1, klength) vector of k-space data\nkdata = nufft_ob(x, ktraj)\n```\n\n### SENSE-NUFFT\n\n[SENSE-NUFFT Example in Colab](https://colab.research.google.com/github/mmuckley/torchkbnufft/blob/main/notebooks/SENSE%20Example.ipynb)\n\nThe package also includes utilities for working with SENSE-NUFFT operators. The\nabove code can be modified to include sensitivity maps.\n\n```python\nsmaps = torch.rand(1, 8, 400, 400) + 1j * torch.rand(1, 8, 400, 400)\nsense_data = nufft_ob(x, ktraj, smaps=smaps.to(x))\n```\n\nThis code first multiplies by the sensitivity coils in ```smaps```, then\ncomputes a 64-length radial spoke for each coil. All operations are broadcast\nacross coils, which minimizes interaction with the Python interpreter, helping\ncomputation speed.\n\n### Sparse Matrix Precomputation\n\n[Sparse Matrix Example in Colab](https://colab.research.google.com/github/mmuckley/torchkbnufft/blob/main/notebooks/Sparse%20Matrix%20Example.ipynb)\n\nSparse matrices are an alternative to table interpolation. Their speed can\nvary, but they are a bit more accurate than standard table mode. The following\ncode calculates sparse interpolation matrices and uses them to compute a single\nradial spoke of k-space data:\n\n```python\nadjnufft_ob = tkbn.KbNufftAdjoint(im_size=im_size)\n\n# precompute the sparse interpolation matrices\ninterp_mats = tkbn.calc_tensor_spmatrix(\n    ktraj,\n    im_size=im_size\n)\n\n# use sparse matrices in adjoint\nimage = adjnufft_ob(kdata, ktraj, interp_mats)\n```\n\nSparse matrix multiplication is only implemented for real numbers in PyTorch,\nwhich can limit their speed.\n\n### Toeplitz Embedding\n\n[Toeplitz Example in Colab](https://colab.research.google.com/github/mmuckley/torchkbnufft/blob/main/notebooks/Toeplitz%20Example.ipynb)\n\nThe package includes routines for calculating embedded Toeplitz kernels and\nusing them as FFT filters for the forward/backward NUFFT operations\n[[3](#references)]. This is very useful for gradient descent algorithms that\nmust use the forward/backward ops in calculating the gradient. The following\ncode shows an example:\n\n```python\ntoep_ob = tkbn.ToepNufft()\n\n# precompute the embedded Toeplitz FFT kernel\nkernel = tkbn.calc_toeplitz_kernel(ktraj, im_size)\n\n# use FFT kernel from embedded Toeplitz matrix\nimage = toep_ob(image, kernel)\n```\n\n### Running on the GPU\n\nAll of the examples included in this repository can be run on the GPU by\nsending the NUFFT object and data to the GPU prior to the function call, e.g.,\n\n```python\nadjnufft_ob = adjnufft_ob.to(torch.device('cuda'))\nkdata = kdata.to(torch.device('cuda'))\nktraj = ktraj.to(torch.device('cuda'))\n\nimage = adjnufft_ob(kdata, ktraj)\n```\n\nPyTorch will throw errors if the underlying ```dtype``` and ```device``` of all\nobjects are not matching. Be sure to make sure your data and NUFFT objects are\non the right device and in the right format to avoid these errors.\n\n## Computation Speed\n\nThe following computation times in seconds were observed on a workstation with\na Xeon E5-2698 CPU and an Nvidia Quadro GP100 GPU for a 15-coil, 405-spoke 2D\nradial problem. CPU computations were limited to 8 threads and done with 64-bit\nfloats, whereas GPU computations were done with 32-bit floats. The benchmark\nused `torchkbnufft` version 1.0.0 and `torch` version 1.7.1.\n\n(n) = normal, (spm) = sparse matrix, (toep) = Toeplitz embedding, (f/b) = forward/backward combined\n\n| Operation      | CPU (n) | CPU (spm) | CPU (toep)  | GPU (n)  | GPU (spm) | GPU (toep)     |\n| -------------- | -------:| ---------:| -----------:| --------:| ---------:| --------------:|\n| Forward NUFFT  | 0.82    | 0.77      | 0.058 (f/b) | 2.58e-02 | 7.44e-02  | 3.03e-03 (f/b) |\n| Adjoint NUFFT  | 0.75    | 0.76      | N/A         | 3.56e-02 | 7.93e-02  | N/A            |\n\nProfiling for your machine can be done by running\n\n```python\npip install -r dev-requirements.txt\npython profile_torchkbnufft.py\n```\n\n## Other Packages\n\nFor users interested in NUFFT implementations for other computing platforms,\nthe following is a partial list of other projects:\n\n1. [TF KB-NUFFT](https://github.com/zaccharieramzi/tfkbnufft) (KB-NUFFT for TensorFlow)\n2. [SigPy](https://github.com/mikgroup/sigpy) (for Numpy arrays, Numba (for CPU) and CuPy (for GPU) backends)\n3. [FINUFFT](https://github.com/flatironinstitute/finufft) (for MATLAB, Python, Julia, C, etc., very efficient)\n4. [NFFT](https://github.com/NFFT/nfft) (for Julia)\n5. [PyNUFFT](https://github.com/jyhmiinlin/pynufft) (for Numpy, also has PyCUDA/PyOpenCL backends)\n\n## References\n\n1. Fessler, J. A., \u0026 Sutton, B. P. (2003). [Nonuniform fast Fourier transforms using min-max interpolation](https://doi.org/10.1109/TSP.2002.807005). *IEEE Transactions on Signal Processing*, 51(2), 560-574.\n\n2. Beatty, P. J., Nishimura, D. G., \u0026 Pauly, J. M. (2005). [Rapid gridding reconstruction with a minimal oversampling ratio](https://doi.org/10.1109/TMI.2005.848376). *IEEE Transactions on Medical Imaging*, 24(6), 799-808.\n\n3. Feichtinger, H. G., Gr, K., \u0026 Strohmer, T. (1995). [Efficient numerical methods in non-uniform sampling theory](https://doi.org/10.1007/s002110050101). *Numerische Mathematik*, 69(4), 423-440.\n\n## Citation\n\nIf you use the package, please cite:\n\n```bibtex\n@conference{muckley:20:tah,\n  author = {M. J. Muckley and R. Stern and T. Murrell and F. Knoll},\n  title = {{TorchKbNufft}: A High-Level, Hardware-Agnostic Non-Uniform Fast {Fourier} Transform},\n  booktitle = {ISMRM Workshop on Data Sampling \\\u0026 Image Reconstruction},\n  year = 2020,\n  note = {Source code available at https://github.com/mmuckley/torchkbnufft},\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmmuckley%2Ftorchkbnufft","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmmuckley%2Ftorchkbnufft","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmmuckley%2Ftorchkbnufft/lists"}