warpkit 1.2.1__tar.gz → 1.2.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. {warpkit-1.2.1 → warpkit-1.2.2}/.github/workflows/build.yml +2 -1
  2. {warpkit-1.2.1 → warpkit-1.2.2}/CLAUDE.md +10 -7
  3. {warpkit-1.2.1 → warpkit-1.2.2}/LICENSE +4 -1
  4. {warpkit-1.2.1 → warpkit-1.2.2}/PKG-INFO +12 -3
  5. {warpkit-1.2.1 → warpkit-1.2.2}/README.md +10 -2
  6. {warpkit-1.2.1 → warpkit-1.2.2}/include/warps.h +24 -12
  7. {warpkit-1.2.1 → warpkit-1.2.2}/pyproject.toml +5 -4
  8. {warpkit-1.2.1 → warpkit-1.2.2}/src/warpkit.cpp +1 -1
  9. {warpkit-1.2.1 → warpkit-1.2.2}/.gitignore +0 -0
  10. {warpkit-1.2.1 → warpkit-1.2.2}/.pre-commit-config.yaml +0 -0
  11. {warpkit-1.2.1 → warpkit-1.2.2}/.python-version +0 -0
  12. {warpkit-1.2.1 → warpkit-1.2.2}/.vscode/c_cpp_properties.json +0 -0
  13. {warpkit-1.2.1 → warpkit-1.2.2}/CMakeLists.txt +0 -0
  14. {warpkit-1.2.1 → warpkit-1.2.2}/Dockerfile +0 -0
  15. {warpkit-1.2.1 → warpkit-1.2.2}/codecov +0 -0
  16. {warpkit-1.2.1 → warpkit-1.2.2}/codecov.SHA256SUM +0 -0
  17. {warpkit-1.2.1 → warpkit-1.2.2}/codecov.SHA256SUM.sig +0 -0
  18. {warpkit-1.2.1 → warpkit-1.2.2}/codecov.yml +0 -0
  19. {warpkit-1.2.1 → warpkit-1.2.2}/include/itk/itkModifiedInvertDisplacementFieldImageFilter.h +0 -0
  20. {warpkit-1.2.1 → warpkit-1.2.2}/include/itk/itkModifiedInvertDisplacementFieldImageFilter.hxx +0 -0
  21. {warpkit-1.2.1 → warpkit-1.2.2}/include/romeo/LICENSE +0 -0
  22. {warpkit-1.2.1 → warpkit-1.2.2}/include/romeo/README.md +0 -0
  23. {warpkit-1.2.1 → warpkit-1.2.2}/include/romeo/algorithm.h +0 -0
  24. {warpkit-1.2.1 → warpkit-1.2.2}/include/romeo/priority_queue.h +0 -0
  25. {warpkit-1.2.1 → warpkit-1.2.2}/include/romeo/romeo.h +0 -0
  26. {warpkit-1.2.1 → warpkit-1.2.2}/include/romeo/seed.h +0 -0
  27. {warpkit-1.2.1 → warpkit-1.2.2}/include/romeo/unwrap.h +0 -0
  28. {warpkit-1.2.1 → warpkit-1.2.2}/include/romeo/utility.h +0 -0
  29. {warpkit-1.2.1 → warpkit-1.2.2}/include/romeo/volume_view.h +0 -0
  30. {warpkit-1.2.1 → warpkit-1.2.2}/include/romeo/voxel_quality.h +0 -0
  31. {warpkit-1.2.1 → warpkit-1.2.2}/include/romeo/weights.h +0 -0
  32. {warpkit-1.2.1 → warpkit-1.2.2}/include/utilities.h +0 -0
  33. {warpkit-1.2.1 → warpkit-1.2.2}/notes/ROMEO_port_plan.md +0 -0
  34. {warpkit-1.2.1 → warpkit-1.2.2}/notes/fmap.png +0 -0
  35. {warpkit-1.2.1 → warpkit-1.2.2}/notes/phase.png +0 -0
  36. {warpkit-1.2.1 → warpkit-1.2.2}/packaging/pyinstaller/build_bundle.py +0 -0
  37. {warpkit-1.2.1 → warpkit-1.2.2}/packaging/pyinstaller/bundle_README.md +0 -0
  38. {warpkit-1.2.1 → warpkit-1.2.2}/packaging/pyinstaller/hooks/hook-warpkit.py +0 -0
  39. {warpkit-1.2.1 → warpkit-1.2.2}/packaging/pyinstaller/launchers/wk-apply-warp.py +0 -0
  40. {warpkit-1.2.1 → warpkit-1.2.2}/packaging/pyinstaller/launchers/wk-compute-fieldmap.py +0 -0
  41. {warpkit-1.2.1 → warpkit-1.2.2}/packaging/pyinstaller/launchers/wk-compute-jacobian.py +0 -0
  42. {warpkit-1.2.1 → warpkit-1.2.2}/packaging/pyinstaller/launchers/wk-convert-fieldmap.py +0 -0
  43. {warpkit-1.2.1 → warpkit-1.2.2}/packaging/pyinstaller/launchers/wk-convert-warp.py +0 -0
  44. {warpkit-1.2.1 → warpkit-1.2.2}/packaging/pyinstaller/launchers/wk-medic.py +0 -0
  45. {warpkit-1.2.1 → warpkit-1.2.2}/packaging/pyinstaller/launchers/wk-unwrap-phase.py +0 -0
  46. {warpkit-1.2.1 → warpkit-1.2.2}/packaging/pyinstaller/warpkit.spec +0 -0
  47. {warpkit-1.2.1 → warpkit-1.2.2}/scripts/check-gitmoji.sh +0 -0
  48. {warpkit-1.2.1 → warpkit-1.2.2}/scripts/regen-stub.sh +0 -0
  49. {warpkit-1.2.1 → warpkit-1.2.2}/tests/conftest.py +0 -0
  50. {warpkit-1.2.1 → warpkit-1.2.2}/tests/data/romeo/Mag.nii +0 -0
  51. {warpkit-1.2.1 → warpkit-1.2.2}/tests/data/romeo/Phase.nii +0 -0
  52. {warpkit-1.2.1 → warpkit-1.2.2}/tests/data/test_data/sub-a01_task-rest_acq-tr1800_echo-1_part-mag_bold.json +0 -0
  53. {warpkit-1.2.1 → warpkit-1.2.2}/tests/data/test_data/sub-a01_task-rest_acq-tr1800_echo-1_part-mag_bold.nii.gz +0 -0
  54. {warpkit-1.2.1 → warpkit-1.2.2}/tests/data/test_data/sub-a01_task-rest_acq-tr1800_echo-1_part-phase_bold.json +0 -0
  55. {warpkit-1.2.1 → warpkit-1.2.2}/tests/data/test_data/sub-a01_task-rest_acq-tr1800_echo-1_part-phase_bold.nii.gz +0 -0
  56. {warpkit-1.2.1 → warpkit-1.2.2}/tests/data/test_data/sub-a01_task-rest_acq-tr1800_echo-2_part-mag_bold.json +0 -0
  57. {warpkit-1.2.1 → warpkit-1.2.2}/tests/data/test_data/sub-a01_task-rest_acq-tr1800_echo-2_part-mag_bold.nii.gz +0 -0
  58. {warpkit-1.2.1 → warpkit-1.2.2}/tests/data/test_data/sub-a01_task-rest_acq-tr1800_echo-2_part-phase_bold.json +0 -0
  59. {warpkit-1.2.1 → warpkit-1.2.2}/tests/data/test_data/sub-a01_task-rest_acq-tr1800_echo-2_part-phase_bold.nii.gz +0 -0
  60. {warpkit-1.2.1 → warpkit-1.2.2}/tests/data/test_data/sub-a01_task-rest_acq-tr1800_echo-3_part-mag_bold.json +0 -0
  61. {warpkit-1.2.1 → warpkit-1.2.2}/tests/data/test_data/sub-a01_task-rest_acq-tr1800_echo-3_part-mag_bold.nii.gz +0 -0
  62. {warpkit-1.2.1 → warpkit-1.2.2}/tests/data/test_data/sub-a01_task-rest_acq-tr1800_echo-3_part-phase_bold.json +0 -0
  63. {warpkit-1.2.1 → warpkit-1.2.2}/tests/data/test_data/sub-a01_task-rest_acq-tr1800_echo-3_part-phase_bold.nii.gz +0 -0
  64. {warpkit-1.2.1 → warpkit-1.2.2}/tests/test_concurrency.py +0 -0
  65. {warpkit-1.2.1 → warpkit-1.2.2}/tests/test_distortion.py +0 -0
  66. {warpkit-1.2.1 → warpkit-1.2.2}/tests/test_model.py +0 -0
  67. {warpkit-1.2.1 → warpkit-1.2.2}/tests/test_romeo.py +0 -0
  68. {warpkit-1.2.1 → warpkit-1.2.2}/tests/test_scripts.py +0 -0
  69. {warpkit-1.2.1 → warpkit-1.2.2}/tests/test_unwrap.py +0 -0
  70. {warpkit-1.2.1 → warpkit-1.2.2}/tests/test_utilities.py +0 -0
  71. {warpkit-1.2.1 → warpkit-1.2.2}/tests/test_version.py +0 -0
  72. {warpkit-1.2.1 → warpkit-1.2.2}/uv.lock +0 -0
  73. {warpkit-1.2.1 → warpkit-1.2.2}/warpkit/__init__.py +0 -0
  74. {warpkit-1.2.1 → warpkit-1.2.2}/warpkit/api.py +0 -0
  75. {warpkit-1.2.1 → warpkit-1.2.2}/warpkit/concurrency.py +0 -0
  76. {warpkit-1.2.1 → warpkit-1.2.2}/warpkit/distortion.py +0 -0
  77. {warpkit-1.2.1 → warpkit-1.2.2}/warpkit/model.py +0 -0
  78. {warpkit-1.2.1 → warpkit-1.2.2}/warpkit/py.typed +0 -0
  79. {warpkit-1.2.1 → warpkit-1.2.2}/warpkit/scripts/__init__.py +0 -0
  80. {warpkit-1.2.1 → warpkit-1.2.2}/warpkit/scripts/_metadata.py +0 -0
  81. {warpkit-1.2.1 → warpkit-1.2.2}/warpkit/scripts/_warp_io.py +0 -0
  82. {warpkit-1.2.1 → warpkit-1.2.2}/warpkit/scripts/apply_warp.py +0 -0
  83. {warpkit-1.2.1 → warpkit-1.2.2}/warpkit/scripts/compute_fieldmap.py +0 -0
  84. {warpkit-1.2.1 → warpkit-1.2.2}/warpkit/scripts/compute_jacobian.py +0 -0
  85. {warpkit-1.2.1 → warpkit-1.2.2}/warpkit/scripts/convert_fieldmap.py +0 -0
  86. {warpkit-1.2.1 → warpkit-1.2.2}/warpkit/scripts/convert_warp.py +0 -0
  87. {warpkit-1.2.1 → warpkit-1.2.2}/warpkit/scripts/medic.py +0 -0
  88. {warpkit-1.2.1 → warpkit-1.2.2}/warpkit/scripts/unwrap_phase.py +0 -0
  89. {warpkit-1.2.1 → warpkit-1.2.2}/warpkit/unwrap.py +0 -0
  90. {warpkit-1.2.1 → warpkit-1.2.2}/warpkit/utilities.py +0 -0
  91. {warpkit-1.2.1 → warpkit-1.2.2}/warpkit/warpkit_cpp.pyi +0 -0
@@ -41,7 +41,8 @@ jobs:
41
41
  {version: '3.11', glob: cp311*},
42
42
  {version: '3.12', glob: cp312*},
43
43
  {version: '3.13', glob: cp313*},
44
- {version: '3.14', glob: cp314*}
44
+ {version: '3.14', glob: cp314-*},
45
+ {version: '3.14t', glob: cp314t*}
45
46
  ]
46
47
  name: Python ${{ matrix.python-versions.version }} wheel on ${{ matrix.os }}
47
48
  runs-on: ${{ matrix.os }}
@@ -10,7 +10,7 @@ DIstortion Correction). Phase unwrapping uses a self-contained C++17 port of
10
10
  **no Julia runtime is involved**; do not reintroduce one (no `julia.py`, no
11
11
  conda recipe, no `FindJulia.cmake`).
12
12
 
13
- Pre-print: <https://www.biorxiv.org/content/10.1101/2023.11.28.568744v1>.
13
+ Paper (Imaging Neuroscience): <https://doi.org/10.1162/IMAG.a.1262>.
14
14
 
15
15
  ## Layout
16
16
 
@@ -131,12 +131,15 @@ and call out anything CI-relevant (wheel matrix, pybind11 ABI, ITK).
131
131
 
132
132
  ## CI specifics
133
133
 
134
- GitHub Actions builds wheels for Python 3.11–3.14 on `ubuntu-latest`,
134
+ GitHub Actions builds wheels for Python 3.11–3.14 (both standard and free-threaded) on `ubuntu-latest`,
135
135
  `ubuntu-24.04-arm`, and `macos-latest` via cibuildwheel.
136
- `pyproject.toml`'s `[tool.cibuildwheel]` skips `*musllinux*` and the
137
- `cp314t-*` free-threaded build; re-enabling free-threaded support requires
138
- auditing the pybind11 + ITK code paths for the no-GIL ABI. The sdist job
139
- also runs `uv run coverage run` then `coverage report -m` — keep coverage
140
- healthy when adding code (the `[tool.coverage.report]` config in
136
+ `pyproject.toml`'s `[tool.cibuildwheel]` skips only `*musllinux*` builds.
137
+ Free-threaded support is enabled via `py::mod_gil_not_used()` in
138
+ `src/warpkit.cpp`. `PyErr_CheckSignals()` calls in `include/warps.h` are
139
+ wrapped in a `WARPKIT_CHECK_SIGNALS()` macro that compiles to a no-op under
140
+ `Py_GIL_DISABLED`, so GIL builds keep Ctrl+C interruptibility during long ITK
141
+ operations and the free-threaded build skips the GIL-requiring check. The
142
+ sdist job also runs `uv run coverage run` then `coverage report -m` — keep
143
+ coverage healthy when adding code (the `[tool.coverage.report]` config in
141
144
  `pyproject.toml` omits the test files). PyPI publish and the GHCR Docker
142
145
  image only run on a published GitHub release.
@@ -1,7 +1,10 @@
1
1
  Copyright (c) 2022 Washington University.
2
2
  Authored by: Andrew Van
3
3
 
4
- Please cite https://www.biorxiv.org/content/10.1101/2023.11.28.568744v1
4
+ Please cite:
5
+ Van AN, Montez DF, Laumann TO, Cho PN, Suljic V, Madison T, et al.
6
+ Frame-wise multi-echo distortion correction for superior functional MRI.
7
+ Imaging Neuroscience 2026; 4 IMAG.a.1262. doi: https://doi.org/10.1162/IMAG.a.1262
5
8
 
6
9
  warpkit is free for non-commercial use by academic, government,
7
10
  and non-profit/not-for-profit institutions. A commercial version of the software is
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: warpkit
3
- Version: 1.2.1
3
+ Version: 1.2.2
4
4
  Summary: A python library for neuroimaging transformations
5
5
  Keywords: neuroimaging
6
6
  Author-Email: Andrew Van <vanandrew77@gmail.com>
@@ -8,6 +8,7 @@ License-File: LICENSE
8
8
  License-File: include/romeo/LICENSE
9
9
  Classifier: Programming Language :: Python :: 3
10
10
  Project-URL: github, https://github.com/vanandrew/warpkit
11
+ Project-URL: paper, https://doi.org/10.1162/IMAG.a.1262
11
12
  Requires-Python: >=3.11
12
13
  Requires-Dist: nibabel>=4.0.2
13
14
  Requires-Dist: numpy>=1.23.3
@@ -21,10 +22,9 @@ Description-Content-Type: text/markdown
21
22
 
22
23
  [![Build](https://github.com/vanandrew/warpkit/actions/workflows/build.yml/badge.svg)](https://github.com/vanandrew/warpkit/actions)
23
24
  [![PyPI](https://img.shields.io/pypi/v/warpkit)](https://pypi.org/project/warpkit/)
24
- [![docker](https://ghcr-badge.egpl.dev/vanandrew/warpkit/latest_tag?trim=major&label=ghcr&nbsp;latest)](https://github.com/vanandrew/warpkit/pkgs/container/warpkit)
25
25
  [![codecov](https://codecov.io/gh/vanandrew/warpkit/graph/badge.svg?token=S6ZZKOAF8V)](https://codecov.io/gh/vanandrew/warpkit)
26
26
 
27
- A Python library for neuroimaging transforms, focused on the Multi-Echo DIstortion Correction (MEDIC) algorithm. The pre-print is available at <https://www.biorxiv.org/content/10.1101/2023.11.28.568744v1>.
27
+ A Python library for neuroimaging transforms, focused on the Multi-Echo DIstortion Correction (MEDIC) algorithm. The paper is published in *Imaging Neuroscience* at <https://doi.org/10.1162/IMAG.a.1262>.
28
28
 
29
29
  The phase-unwrapping core is a self-contained C++17 port of [ROMEO](https://github.com/korbinian90/ROMEO) — there is no Julia runtime to install, and binary wheels ship with the ITK pieces statically linked. If you used an older release of warpkit that required `julia` on `PATH`, that step is gone.
30
30
 
@@ -213,6 +213,15 @@ wk-convert-fieldmap \
213
213
  --output sub-01_run-01_fieldmap.nii
214
214
  ```
215
215
 
216
+ ## Citation
217
+
218
+ If you use warpkit, please cite:
219
+
220
+ > Van AN, Montez DF, Laumann TO, Cho PN, Suljic V, Madison T, et al.
221
+ > Frame-wise multi-echo distortion correction for superior functional MRI.
222
+ > *Imaging Neuroscience* 2026; 4 IMAG.a.1262.
223
+ > doi: <https://doi.org/10.1162/IMAG.a.1262>
224
+
216
225
  ## Authors
217
226
 
218
227
  Vahdeta Suljic &lt;suljic@wustl.edu&gt;, Andrew Van &lt;vanandrew77@gmail.com&gt;
@@ -2,10 +2,9 @@
2
2
 
3
3
  [![Build](https://github.com/vanandrew/warpkit/actions/workflows/build.yml/badge.svg)](https://github.com/vanandrew/warpkit/actions)
4
4
  [![PyPI](https://img.shields.io/pypi/v/warpkit)](https://pypi.org/project/warpkit/)
5
- [![docker](https://ghcr-badge.egpl.dev/vanandrew/warpkit/latest_tag?trim=major&label=ghcr&nbsp;latest)](https://github.com/vanandrew/warpkit/pkgs/container/warpkit)
6
5
  [![codecov](https://codecov.io/gh/vanandrew/warpkit/graph/badge.svg?token=S6ZZKOAF8V)](https://codecov.io/gh/vanandrew/warpkit)
7
6
 
8
- A Python library for neuroimaging transforms, focused on the Multi-Echo DIstortion Correction (MEDIC) algorithm. The pre-print is available at <https://www.biorxiv.org/content/10.1101/2023.11.28.568744v1>.
7
+ A Python library for neuroimaging transforms, focused on the Multi-Echo DIstortion Correction (MEDIC) algorithm. The paper is published in *Imaging Neuroscience* at <https://doi.org/10.1162/IMAG.a.1262>.
9
8
 
10
9
  The phase-unwrapping core is a self-contained C++17 port of [ROMEO](https://github.com/korbinian90/ROMEO) — there is no Julia runtime to install, and binary wheels ship with the ITK pieces statically linked. If you used an older release of warpkit that required `julia` on `PATH`, that step is gone.
11
10
 
@@ -194,6 +193,15 @@ wk-convert-fieldmap \
194
193
  --output sub-01_run-01_fieldmap.nii
195
194
  ```
196
195
 
196
+ ## Citation
197
+
198
+ If you use warpkit, please cite:
199
+
200
+ > Van AN, Montez DF, Laumann TO, Cho PN, Suljic V, Madison T, et al.
201
+ > Frame-wise multi-echo distortion correction for superior functional MRI.
202
+ > *Imaging Neuroscience* 2026; 4 IMAG.a.1262.
203
+ > doi: <https://doi.org/10.1162/IMAG.a.1262>
204
+
197
205
  ## Authors
198
206
 
199
207
  Vahdeta Suljic &lt;suljic@wustl.edu&gt;, Andrew Van &lt;vanandrew77@gmail.com&gt;
@@ -19,6 +19,18 @@
19
19
 
20
20
  namespace py = pybind11;
21
21
 
22
+ // PyErr_CheckSignals() needs the GIL; free-threaded builds (Py_GIL_DISABLED)
23
+ // declare `py::mod_gil_not_used()` and skip the check, trading Ctrl+C
24
+ // interruptibility during long ITK operations for no-GIL execution.
25
+ #ifdef Py_GIL_DISABLED
26
+ #define WARPKIT_CHECK_SIGNALS() ((void)0)
27
+ #else
28
+ #define WARPKIT_CHECK_SIGNALS() \
29
+ do { \
30
+ if (PyErr_CheckSignals() != 0) throw py::error_already_set(); \
31
+ } while (0)
32
+ #endif
33
+
22
34
  /**
23
35
  * @brief Invert a displacement map
24
36
  *
@@ -139,9 +151,9 @@ py::array_t<T, py::array::f_style> invert_displacement_map(py::array_t<T, py::ar
139
151
 
140
152
  // Get output
141
153
  typename DisplacementMapType::Pointer inv_map = identity_filter->GetOutput();
142
- if (PyErr_CheckSignals() != 0) throw py::error_already_set();
154
+ WARPKIT_CHECK_SIGNALS();
143
155
  inv_map->Update();
144
- if (PyErr_CheckSignals() != 0) throw py::error_already_set();
156
+ WARPKIT_CHECK_SIGNALS();
145
157
  itk::ImageRegionConstIteratorWithIndex<DisplacementMapType> inv_map_it(inv_map,
146
158
  inv_map->GetLargestPossibleRegion());
147
159
  py::array_t<T, py::array::f_style> inverted_displacement_map(displacement_map);
@@ -170,7 +182,7 @@ py::array_t<T, py::array::f_style> invert_displacement_field(py::array_t<T, py::
170
182
  py::array_t<T, py::array::f_style> direction,
171
183
  py::array_t<T, py::array::f_style> spacing,
172
184
  ssize_t iterations, bool verbose) {
173
- if (PyErr_CheckSignals() != 0) throw py::error_already_set();
185
+ WARPKIT_CHECK_SIGNALS();
174
186
 
175
187
  // Get the displacement field shape
176
188
  const ssize_t* shape = displacement_field.shape();
@@ -227,9 +239,9 @@ py::array_t<T, py::array::f_style> invert_displacement_field(py::array_t<T, py::
227
239
 
228
240
  // Get output
229
241
  typename DisplacementFieldType::Pointer inv_field = invert_displacement_filter->GetOutput();
230
- if (PyErr_CheckSignals() != 0) throw py::error_already_set();
242
+ WARPKIT_CHECK_SIGNALS();
231
243
  inv_field->Update();
232
- if (PyErr_CheckSignals() != 0) throw py::error_already_set();
244
+ WARPKIT_CHECK_SIGNALS();
233
245
  itk::ImageRegionConstIteratorWithIndex<DisplacementFieldType> inv_field_it(inv_field,
234
246
  inv_field->GetLargestPossibleRegion());
235
247
  py::array_t<T, py::array::f_style> inverted_displacement_field(displacement_field);
@@ -261,7 +273,7 @@ py::array_t<T, py::array::f_style> compute_jacobian_determinant(py::array_t<T, p
261
273
  py::array_t<T, py::array::f_style> origin,
262
274
  py::array_t<T, py::array::f_style> direction,
263
275
  py::array_t<T, py::array::f_style> spacing) {
264
- if (PyErr_CheckSignals() != 0) throw py::error_already_set();
276
+ WARPKIT_CHECK_SIGNALS();
265
277
 
266
278
  // Get the displacement field shape
267
279
  const ssize_t* shape = displacement_field.shape();
@@ -315,9 +327,9 @@ py::array_t<T, py::array::f_style> compute_jacobian_determinant(py::array_t<T, p
315
327
  // Get the jacobian determinant fields
316
328
  typename DisplacementFieldJacobianDeterminantFilterType::OutputImagePointer jacobian_determinant =
317
329
  jacobian_filter->GetOutput();
318
- if (PyErr_CheckSignals() != 0) throw py::error_already_set();
330
+ WARPKIT_CHECK_SIGNALS();
319
331
  jacobian_determinant->Update();
320
- if (PyErr_CheckSignals() != 0) throw py::error_already_set();
332
+ WARPKIT_CHECK_SIGNALS();
321
333
 
322
334
  // Convert to numpy array
323
335
  py::array_t<T, py::array::f_style> jacobian_determinant_array({shape[0], shape[1], shape[2]});
@@ -461,9 +473,9 @@ py::array_t<T, py::array::f_style> resample(
461
473
 
462
474
  // Get the output
463
475
  typename OutputImageType::Pointer output_image = warp_filter->GetOutput();
464
- if (PyErr_CheckSignals() != 0) throw py::error_already_set();
476
+ WARPKIT_CHECK_SIGNALS();
465
477
  output_image->Update();
466
- if (PyErr_CheckSignals() != 0) throw py::error_already_set();
478
+ WARPKIT_CHECK_SIGNALS();
467
479
  itk::ImageRegionConstIteratorWithIndex<OutputImageType> output_iterator(output_image,
468
480
  output_image->GetLargestPossibleRegion());
469
481
  py::array_t<T, py::array::f_style> output_array({output_shape.at(0), output_shape.at(1), output_shape.at(2)});
@@ -481,7 +493,7 @@ T compute_hausdorff_distance(
481
493
  py::array_t<T, py::array::f_style> image1_direction, py::array_t<T, py::array::f_style> image1_spacing,
482
494
  py::array_t<T, py::array::f_style> image2, py::array_t<T, py::array::f_style> image2_origin,
483
495
  py::array_t<T, py::array::f_style> image2_direction, py::array_t<T, py::array::f_style> image2_spacing) {
484
- if (PyErr_CheckSignals() != 0) throw py::error_already_set();
496
+ WARPKIT_CHECK_SIGNALS();
485
497
 
486
498
  // Setup types
487
499
  using ImageType = typename itk::Image<T, 3>;
@@ -545,7 +557,7 @@ T compute_hausdorff_distance(
545
557
  // Get the hausdorff distance
546
558
  hausdorff_filter->Update();
547
559
  T hausdorff_distance = hausdorff_filter->GetAverageHausdorffDistance();
548
- if (PyErr_CheckSignals() != 0) throw py::error_already_set();
560
+ WARPKIT_CHECK_SIGNALS();
549
561
 
550
562
  // Return the hausdorff distance
551
563
  return hausdorff_distance;
@@ -6,7 +6,7 @@ requires-python = ">=3.11"
6
6
  authors = [{ name = "Andrew Van", email = "vanandrew77@gmail.com" }]
7
7
  keywords = ["neuroimaging"]
8
8
  classifiers = ["Programming Language :: Python :: 3"]
9
- urls = { github = "https://github.com/vanandrew/warpkit" }
9
+ urls = { github = "https://github.com/vanandrew/warpkit", paper = "https://doi.org/10.1162/IMAG.a.1262" }
10
10
  # include/romeo/LICENSE is the upstream MIT notice for the ROMEO C++ port; it
11
11
  # travels with the headers in source distributions and (via PEP 639
12
12
  # license-files) gets bundled into wheels under *.dist-info/licenses/.
@@ -122,9 +122,10 @@ command_line = "-m pytest"
122
122
  omit = ["tests/*"]
123
123
 
124
124
  [tool.cibuildwheel]
125
- # Skip musllinux (we ship manylinux only) and free-threaded CPython builds
126
- # (cp31Xt-*) our pybind11 bindings + ITK haven't been audited for the no-GIL ABI.
127
- skip = "*musllinux* cp314t-*"
125
+ # Skip musllinux (we ship manylinux only). Free-threaded (cp31Xt-*) builds
126
+ # are kept: warps.h guards PyErr_CheckSignals() behind WARPKIT_CHECK_SIGNALS,
127
+ # which is a no-op under Py_GIL_DISABLED.
128
+ skip = "*musllinux*"
128
129
  build-frontend = "build"
129
130
  build-verbosity = 3
130
131
 
@@ -5,7 +5,7 @@
5
5
 
6
6
  namespace py = pybind11;
7
7
 
8
- PYBIND11_MODULE(warpkit_cpp, m) {
8
+ PYBIND11_MODULE(warpkit_cpp, m, py::mod_gil_not_used()) {
9
9
  m.def("calculate_weights", &romeo::calculate_weights<float>,
10
10
  "ROMEO edge-weight map (3, nx, ny, nz) uint8. Exposed for port validation; not used by warpkit.",
11
11
  py::arg("phase"),
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes