gaara 0.1.0__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 (39) hide show
  1. gaara-0.1.0/.gitignore +69 -0
  2. gaara-0.1.0/LICENSE +28 -0
  3. gaara-0.1.0/PKG-INFO +23 -0
  4. gaara-0.1.0/README.md +29 -0
  5. gaara-0.1.0/gaara/__init__.py +49 -0
  6. gaara-0.1.0/gaara/fastgaara.cpp +72 -0
  7. gaara-0.1.0/libcrackle/LICENSE +29 -0
  8. gaara-0.1.0/libcrackle/builtins.hpp +50 -0
  9. gaara-0.1.0/libcrackle/cc3d.hpp +406 -0
  10. gaara-0.1.0/libcrackle/crackcodes.hpp +881 -0
  11. gaara-0.1.0/libcrackle/crackle.hpp +1134 -0
  12. gaara-0.1.0/libcrackle/crc.hpp +63 -0
  13. gaara-0.1.0/libcrackle/crc32c_arm.h +133 -0
  14. gaara-0.1.0/libcrackle/crc32c_portable.h +221 -0
  15. gaara-0.1.0/libcrackle/crc32c_portable.hpp +221 -0
  16. gaara-0.1.0/libcrackle/crc32c_x86_64_sse.h +168 -0
  17. gaara-0.1.0/libcrackle/dual_graph.hpp +280 -0
  18. gaara-0.1.0/libcrackle/header.hpp +314 -0
  19. gaara-0.1.0/libcrackle/labels.hpp +653 -0
  20. gaara-0.1.0/libcrackle/lib.hpp +261 -0
  21. gaara-0.1.0/libcrackle/markov.hpp +493 -0
  22. gaara-0.1.0/libcrackle/operations.hpp +1357 -0
  23. gaara-0.1.0/libcrackle/pairing_heap.hpp +348 -0
  24. gaara-0.1.0/libcrackle/pins.hpp +408 -0
  25. gaara-0.1.0/libcrackle/robin_hood.hpp +2546 -0
  26. gaara-0.1.0/libcrackle/threadpool.hpp +136 -0
  27. gaara-0.1.0/lookup_tables/Makefile +18 -0
  28. gaara-0.1.0/lookup_tables/README.md +65 -0
  29. gaara-0.1.0/lookup_tables/src/cc3d.hpp +1493 -0
  30. gaara-0.1.0/lookup_tables/src/isthmus.cpp +161 -0
  31. gaara-0.1.0/lookup_tables/src/simple.cpp +232 -0
  32. gaara-0.1.0/lookup_tables/tables/isthmus.bin +0 -0
  33. gaara-0.1.0/lookup_tables/tables/simple.bin +0 -0
  34. gaara-0.1.0/meson.build +39 -0
  35. gaara-0.1.0/pyproject.toml +31 -0
  36. gaara-0.1.0/src/def.hpp +145 -0
  37. gaara-0.1.0/src/gaara_binary.hpp +535 -0
  38. gaara-0.1.0/src/gaara_multilabel.hpp +537 -0
  39. gaara-0.1.0/src/gaara_test.cpp +232 -0
gaara-0.1.0/.gitignore ADDED
@@ -0,0 +1,69 @@
1
+ # Prerequisites
2
+ *.d
3
+
4
+ # Compiled Object files
5
+ *.slo
6
+ *.lo
7
+ *.o
8
+ *.obj
9
+
10
+ # Precompiled Headers
11
+ *.gch
12
+ *.pch
13
+
14
+ # Linker files
15
+ *.ilk
16
+
17
+ # Debugger Files
18
+ *.pdb
19
+
20
+ # Compiled Dynamic libraries
21
+ *.so
22
+ *.dylib
23
+ *.dll
24
+ *.so.*
25
+
26
+
27
+ # Fortran module files
28
+ *.mod
29
+ *.smod
30
+
31
+ # Compiled Static libraries
32
+ *.lai
33
+ *.la
34
+ *.a
35
+ *.lib
36
+
37
+ # Executables
38
+ *.exe
39
+ *.out
40
+ *.app
41
+
42
+ # Build directories
43
+ build/
44
+ Build/
45
+ build-*/
46
+
47
+ # CMake generated files
48
+ CMakeFiles/
49
+ CMakeCache.txt
50
+ cmake_install.cmake
51
+ Makefile
52
+ install_manifest.txt
53
+ compile_commands.json
54
+
55
+ # Temporary files
56
+ *.tmp
57
+ *.log
58
+ *.bak
59
+ *.swp
60
+
61
+ # vcpkg
62
+ vcpkg_installed/
63
+
64
+ # debug information files
65
+ *.dwo
66
+
67
+ # test output & cache
68
+ Testing/
69
+ .cache/
gaara-0.1.0/LICENSE ADDED
@@ -0,0 +1,28 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2026, William Silversmith
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ 3. Neither the name of the copyright holder nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
gaara-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,23 @@
1
+ Metadata-Version: 2.4
2
+ Name: gaara
3
+ Version: 0.1.0
4
+ Summary: Skeleton generation via 3D voxel thinning.
5
+ License-Expression: BSD-3-Clause
6
+ Classifier: Intended Audience :: Developers
7
+ Classifier: Development Status :: 3 - Alpha
8
+ Classifier: Programming Language :: Python
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3.10
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Classifier: Programming Language :: Python :: 3.14
15
+ Classifier: Topic :: Scientific/Engineering :: Image Processing
16
+ Classifier: Intended Audience :: Science/Research
17
+ Classifier: Operating System :: POSIX
18
+ Classifier: Operating System :: MacOS
19
+ Classifier: Operating System :: Microsoft :: Windows :: Windows 10
20
+ Classifier: Topic :: Utilities
21
+ Requires-Python: >=3.10
22
+ Requires-Dist: numpy
23
+
gaara-0.1.0/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # gaara
2
+ Skeleton thinning algorithm for large images.
3
+
4
+ ```python
5
+ import gaara
6
+ import numpy as np
7
+
8
+ arr = np.load(...) # some 3d array in fortran order
9
+
10
+ # binary images are slightly more efficient to process
11
+ # 80% of the memory and slightly faster.
12
+
13
+ arr = gaara.skeletonize(arr, binary_image=True, in_place=False)
14
+ arr = gaara.skeletonize(arr, binary_image=False, in_place=False)
15
+ ```
16
+
17
+ Gaara is a skeletion generation via voxel thinning algorithm based on Palágyi's 2014 paper [1] and inspired by Matejek et al.'s work on [synapseaware](https://github.com/Rhoana/synapseaware/). [2]
18
+
19
+ While efficient and fine for tracing neurites that have a natural tree structure, a shortcoming of [Kimimaro](https://github.com/seung-lab/kimimaro) is its inability to generate topologically correct skeletons [3] which have applications to e.g. glia and blood vessels.
20
+
21
+ Gaara attempts to be an efficient voxel thinning algorithm implementation that can handle very large images on a single machine by making use of crackle compression dynamically.
22
+
23
+ ## References
24
+
25
+ 1. K. Palágyi et al., “A Sequential 3D Thinning Algorithm and Its Medical Applications,” in Information Processing in Medical Imaging, M. F. Insana and R. M. Leahy, Eds., Berlin, Heidelberg: Springer, 2001, pp. 409–415. doi: 10.1007/3-540-45729-1_42.
26
+
27
+ 2. B. Matejek, D. Wei, X. Wang, J. Zhao, K. Palágyi, and H. Pfister, “Synapse-Aware Skeleton Generation for Neural Circuits,” in Medical Image Computing and Computer Assisted Intervention – MICCAI 2019, D. Shen, T. Liu, T. M. Peters, L. H. Staib, C. Essert, S. Zhou, P.-T. Yap, and A. Khan, Eds., Cham: Springer International Publishing, 2019, pp. 227–235. doi: 10.1007/978-3-030-32239-7_26.
28
+
29
+ 3. T. A. Syed, M. Youssef, A. L. Schober, Y. Kubota, K. K. Murai, and C. K. Salmon, “Beyond Neurons: Computer Vision Methods for Analysis of Morphologically Complex Astrocytes,” Frontiers in Computer Science, vol. 6, Sep. 2024, doi: 10.3389/fcomp.2024.1156204.
@@ -0,0 +1,49 @@
1
+ import numpy as np
2
+ import numpy.typing as npt
3
+
4
+ from . import fastgaara
5
+
6
+ __all__ = ["skeletonize"]
7
+
8
+ def skeletonize(
9
+ labels:npt.NDArray[np.integer],
10
+ binary_image:bool = False,
11
+ in_place:bool = False
12
+ ) -> npt.NDArray[np.integer]:
13
+ """
14
+ Apply Palagyi's 3D voxel thinning algorithm to `labels`, a binary image.
15
+
16
+ Reference:
17
+
18
+ K. Palágyi, "A Sequential 3D Curve-Thinning Algorithm Based on Isthmuses,"
19
+ in Advances in Visual Computing, vol. 8888,
20
+ G. Bebis, R. Boyle, B. Parvin, D. Koracin, R. McMahan, J. Jerald,
21
+ H. Zhang, S. M. Drucker, C. Kambhamettu, M. El Choubassi, Z. Deng,
22
+ and M. Carlson, Eds.,
23
+ Cham: Springer International Publishing, 2014, pp. 406–415.
24
+ doi: 10.1007/978-3-319-14364-4_39.
25
+ """
26
+ if labels.ndim != 3:
27
+ raise ValueError(f"This function only supports 3D images. Got: {labels.shape}")
28
+
29
+ if labels.size <= 1:
30
+ return labels
31
+
32
+ if in_place and not labels.flags.f_contiguous:
33
+ raise ValueError("Cannot perform an in-place operation on non-Fortran ordered data.")
34
+ elif not in_place:
35
+ labels = np.copy(labels, order="F")
36
+
37
+ orig_dtype = labels.dtype
38
+ if labels.dtype == bool:
39
+ binary_image = True
40
+ labels = labels.view(np.uint8)
41
+
42
+ if binary_image:
43
+ fastgaara.thin_palagyi_binary(labels)
44
+ else:
45
+ fastgaara.thin_palagyi_multilabel(labels)
46
+
47
+ return labels.view(orig_dtype)
48
+
49
+
@@ -0,0 +1,72 @@
1
+ #define PYBIND11_DETAILED_ERROR_MESSAGES
2
+
3
+ #include <pybind11/pybind11.h>
4
+ #include <pybind11/numpy.h>
5
+ #include <pybind11/stl.h>
6
+
7
+ #include <cstdlib>
8
+ #include <cmath>
9
+
10
+ #include "gaara_binary.hpp"
11
+ #include "gaara_multilabel.hpp"
12
+
13
+ namespace py = pybind11;
14
+
15
+ template <typename Func>
16
+ void dispatch_skeletonize(const py::array& labels, Func&& func) {
17
+ py::dtype dt = labels.dtype();
18
+ const int width = dt.itemsize();
19
+
20
+ const uint64_t sx = labels.shape()[0];
21
+ const uint64_t sy = labels.shape()[1];
22
+ const uint64_t sz = labels.ndim() > 2
23
+ ? labels.shape()[2]
24
+ : 1;
25
+
26
+ void* data = const_cast<void*>(labels.data());
27
+
28
+ if (width == 1) {
29
+ func(static_cast<uint8_t*>(data), sx, sy, sz);
30
+ }
31
+ else if (width == 2) {
32
+ func(static_cast<uint16_t*>(data), sx, sy, sz);
33
+ }
34
+ else if (width == 4) {
35
+ func(static_cast<uint32_t*>(data), sx, sy, sz);
36
+ }
37
+ else {
38
+ func(static_cast<uint64_t*>(data), sx, sy, sz);
39
+ }
40
+ }
41
+
42
+ // assumes fortran order
43
+ py::array thin_palagyi_binary(const py::array& labels) {
44
+ dispatch_skeletonize(labels, [](auto *data, uint64_t sx, uint64_t sy, uint64_t sz) {
45
+ using T = std::remove_pointer_t<decltype(data)>;
46
+ return gaara::binary::skeletonize<T>(
47
+ data,
48
+ sx, sy, sz
49
+ );
50
+ });
51
+
52
+ return labels;
53
+ }
54
+
55
+ // assumes fortran order
56
+ py::array thin_palagyi_multilabel(const py::array& labels) {
57
+ dispatch_skeletonize(labels, [](auto *data, uint64_t sx, uint64_t sy, uint64_t sz) {
58
+ using T = std::remove_pointer_t<decltype(data)>;
59
+ return gaara::multilabel::skeletonize<T>(
60
+ data,
61
+ sx, sy, sz
62
+ );
63
+ });
64
+
65
+ return labels;
66
+ }
67
+
68
+ PYBIND11_MODULE(fastgaara, m) {
69
+ m.doc() = "Python interface for Gaara C++ functions.";
70
+ m.def("thin_palagyi_binary", &thin_palagyi_binary, "Perform morphological thinning using the Palagyi algorithm on a binary 3D image.");
71
+ m.def("thin_palagyi_multilabel", &thin_palagyi_multilabel, "Perform morphological thinning using the Palagyi algorithm on a binary 3D image.");
72
+ }
@@ -0,0 +1,29 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2022-2026 William Silversmith
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ 1. Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ 3. Neither the name of the copyright holder nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,50 @@
1
+ #ifndef _CRACKLE_BUILTINS_HXX_
2
+ #define _CRACKLE_BUILTINS_HXX_
3
+
4
+
5
+ #ifdef _MSC_VER
6
+ # include <intrin.h>
7
+ # define popcount __popcnt
8
+
9
+ // https://stackoverflow.com/questions/355967/how-to-use-msvc-intrinsics-to-get-the-equivalent-of-this-gcc-code
10
+ unsigned long ctz(unsigned long value) {
11
+ unsigned long trailing_zero = 0;
12
+ if (_BitScanForward(&trailing_zero, value)) {
13
+ return trailing_zero;
14
+ }
15
+ else {
16
+ return 32;
17
+ }
18
+ }
19
+ #else
20
+ # define popcount __builtin_popcount
21
+ # define ctz __builtin_ctz
22
+ #endif
23
+
24
+ uint32_t ffs (uint32_t x) {
25
+ #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
26
+ return __builtin_ffs(x);
27
+ #elif defined _MSC_VER
28
+ /* _BitScanForward
29
+ <https://docs.microsoft.com/en-us/cpp/intrinsics/bitscanforward-bitscanforward64> */
30
+ unsigned long bit;
31
+ if (_BitScanForward (&bit, x)) {
32
+ return bit + 1;
33
+ }
34
+ return 0;
35
+ #else
36
+ if (x == 0) {
37
+ return 0;
38
+ }
39
+ constexpr uint32_t num_bits = sizeof(x) * 8;
40
+ for (uint32_t i = 0; i < num_bits; i++) {
41
+ if ((x >> i) & 0x1) {
42
+ return i + 1;
43
+ }
44
+ }
45
+ return 0;
46
+ #endif
47
+ }
48
+
49
+
50
+ #endif