feat: Introduce Fast_OS_SART and Adaptive-Weighted TV to ART algorithms - #751
feat: Introduce Fast_OS_SART and Adaptive-Weighted TV to ART algorithms#751Paramveersingh-S wants to merge 8 commits into
Conversation
|
Fantastic! For some reason I had in mind Nesterov was already in the code, but its only in MATLAB! However, OS-/SART with TV/AwTV min exists already: AwASD_POCS , OS_AwASD_POCS https://github.com/CERN/TIGRE/blob/master/Python/tigre/algorithms/pocs_algorithms.py#L411 |
|
Ah, my mistake! Thank you for pointing that out—I see now that I've gone ahead and removed the redundant I have also updated the PR description to reflect this. Let me know if you'd like any additional benchmarks or tests for |
|
Thanks! I'll have a look later, mostly to make sure the API is similar enough to the MATLAB version |
|
I tested the fast_os_sart independently on my problems, it has speed gain about 4x - 8x. Just need to be aware early stopping to avoid run into noise problem. |
|
The way this exists in MATLAB is different, and we should try to make them the same API. eg in SIRT: TIGRE/MATLAB/Algorithms/SIRT.m Lines 107 to 113 in 2c430bb then TIGRE/MATLAB/Algorithms/SIRT.m Lines 134 to 142 in 2c430bb . For coherence, we should make this the same in python, rather than creating new algorithms to import. Do you mind doing those changes. @Paramveersingh-S ? |
|
I will try to do this |
… (addresses maintainer review)
| t_old = t | ||
| t = (1.0 + np.sqrt(1.0 + 4.0 * t ** 2)) / 2.0 | ||
| y_rec = self.res + (t_old - 1.0) / t * (self.res - x_rec_old) | ||
| y_rec = np.float32(y_rec) |
|
@AnderBiguri It was originally there because t is a float64, meaning the multiplication (t_old - 1.0) / t * (self.res - x_rec_old) was upcasting the entire 3D y_rec array to float64. This caused a type mismatch crash when passed to the TIGRE C++ backend, which expects float32. However, casting the entire array back to float32 afterwards was allocating a large, unnecessary float64 array in memory. I've just pushed a commit that fixes this by casting the scalar multiplier instead: This is much more memory efficient, as it guarantees the operation stays in float32 without needing an array-wide cast. |
Nesterov extrapolation before each subset pass, classical t-schedule. PR is open/unmerged upstream; implemented here against this fork's in-place res convention. Measured on the Minerals_Tomosynthesis rockbed (250 views, N0 1e5): traverses the OS-SART sharpness/noise frontier ~8x faster (fast i50 = os_sart i400 to the third digit on both PSF and sigma), and reaches the noise-fitting regime 8x faster too -- at i200 the volume decomposes into banded noise (sigma +80%) and rod FWHMs drop below their physical projected width (overshoot ringing). Use with early stopping; judge on the frontier, never at matched iterations -- the docstring says so.

Summary
This PR introduces three new state-of-the-art algebraic reconstruction algorithms to the
art_family_algorithmsmodule, significantly improving convergence speed and edge-preservation capabilities.Additions
Fast_OS_SART(Nesterov-Accelerated OS-SART)Introduced Nesterov momentum acceleration to the
OS_SARTalgorithm. By applying the standardAwSART_TV&AwOSSART_TV(Adaptive-Weighted Total Variation)Standard TV regularization inside SART often suffers from "staircasing" artifacts and over-smooths delicate biological boundaries. By bridging the ART family with TIGRE's existing
minimizeAwTVfunction, these algorithms utilize an anisotropic edge-indicator function to perform aggressive noise reduction while strictly preserving sharp image edges.Implementation Details
run_main_iter()by overriding the baseIterativeReconAlglogic.dataminimizingstructure.__init__.py.Let me know if there are any specific performance benchmarks or phantom tests you'd like me to run to further validate these additions!