packingcubes 0.2.3__tar.gz → 0.3.1__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 (70) hide show
  1. {packingcubes-0.2.3 → packingcubes-0.3.1}/.github/workflows/ci.yml +1 -1
  2. packingcubes-0.3.1/.github/workflows/docs.yml +29 -0
  3. {packingcubes-0.2.3 → packingcubes-0.3.1}/.github/workflows/pypi-publish.yml +1 -1
  4. packingcubes-0.3.1/.readthedocs.yaml +19 -0
  5. {packingcubes-0.2.3 → packingcubes-0.3.1}/CHANGELOG.md +124 -0
  6. {packingcubes-0.2.3 → packingcubes-0.3.1}/PKG-INFO +1 -1
  7. packingcubes-0.3.1/docs/index.md +6 -0
  8. packingcubes-0.3.1/docs/javascripts/mathjax.js +24 -0
  9. {packingcubes-0.2.3/doc → packingcubes-0.3.1/docs}/packed_format.md +47 -6
  10. {packingcubes-0.2.3 → packingcubes-0.3.1}/examples/Profiling.py +52 -12
  11. {packingcubes-0.2.3 → packingcubes-0.3.1}/packingcubes/__init__.py +15 -1
  12. {packingcubes-0.2.3 → packingcubes-0.3.1}/packingcubes/bounding_box.py +63 -24
  13. packingcubes-0.3.1/packingcubes/cubes/__init__.py +23 -0
  14. packingcubes-0.3.1/packingcubes/cubes/cubes_creation.py +539 -0
  15. packingcubes-0.3.1/packingcubes/cubes/cubes_numba.py +637 -0
  16. packingcubes-0.3.1/packingcubes/cubes/multi_cubes.py +403 -0
  17. packingcubes-0.3.1/packingcubes/cubes/particle_cubes.py +447 -0
  18. {packingcubes-0.2.3 → packingcubes-0.3.1}/packingcubes/data_objects.py +46 -11
  19. packingcubes-0.3.1/packingcubes/packed_tree/fixed_distance_heap.py +281 -0
  20. {packingcubes-0.2.3 → packingcubes-0.3.1}/packingcubes/packed_tree/kdtree.py +109 -66
  21. {packingcubes-0.2.3 → packingcubes-0.3.1}/packingcubes/packed_tree/packed_node.py +1 -1
  22. {packingcubes-0.2.3 → packingcubes-0.3.1}/packingcubes/packed_tree/packed_tree.py +28 -20
  23. {packingcubes-0.2.3 → packingcubes-0.3.1}/packingcubes/packed_tree/packed_tree_numba.py +103 -132
  24. {packingcubes-0.2.3 → packingcubes-0.3.1}/packingcubes.egg-info/PKG-INFO +1 -1
  25. {packingcubes-0.2.3 → packingcubes-0.3.1}/packingcubes.egg-info/SOURCES.txt +24 -7
  26. packingcubes-0.3.1/packingcubes.egg-info/entry_points.txt +4 -0
  27. {packingcubes-0.2.3 → packingcubes-0.3.1}/pixi.lock +452 -29
  28. {packingcubes-0.2.3 → packingcubes-0.3.1}/pyproject.toml +15 -2
  29. packingcubes-0.3.1/tests/performance/__init__.py +0 -0
  30. packingcubes-0.3.1/tests/performance/brute.py +27 -0
  31. packingcubes-0.3.1/tests/performance/cubes.py +21 -0
  32. packingcubes-0.3.1/tests/performance/json_parsing.py +24 -0
  33. packingcubes-0.3.1/tests/performance/kdtree.py +40 -0
  34. packingcubes-0.3.1/tests/performance/octree.py +20 -0
  35. packingcubes-0.3.1/tests/performance/packed_tree.py +64 -0
  36. packingcubes-0.3.1/tests/performance/plot_timings.py +486 -0
  37. packingcubes-0.3.1/tests/performance/scipy.py +34 -0
  38. packingcubes-0.3.1/tests/performance/timing.py +1144 -0
  39. {packingcubes-0.2.3 → packingcubes-0.3.1}/tests/test_bounding_box.py +11 -5
  40. {packingcubes-0.2.3 → packingcubes-0.3.1}/tests/test_kdtree.py +3 -1
  41. packingcubes-0.3.1/zensical.toml +334 -0
  42. packingcubes-0.2.3/examples/Benchmarking.py +0 -780
  43. packingcubes-0.2.3/examples/timing_tests.py +0 -1000
  44. packingcubes-0.2.3/examples/timing_tests.sh +0 -42
  45. packingcubes-0.2.3/packingcubes/cubes.py +0 -1023
  46. packingcubes-0.2.3/packingcubes.egg-info/entry_points.txt +0 -2
  47. {packingcubes-0.2.3 → packingcubes-0.3.1}/.gitattributes +0 -0
  48. {packingcubes-0.2.3 → packingcubes-0.3.1}/.github/dependabot.yml +0 -0
  49. {packingcubes-0.2.3 → packingcubes-0.3.1}/.github/workflows/ruff.yml +0 -0
  50. {packingcubes-0.2.3 → packingcubes-0.3.1}/.gitignore +0 -0
  51. {packingcubes-0.2.3 → packingcubes-0.3.1}/.gitlint +0 -0
  52. {packingcubes-0.2.3 → packingcubes-0.3.1}/.pre-commit-config.yaml +0 -0
  53. {packingcubes-0.2.3 → packingcubes-0.3.1}/LICENSE +0 -0
  54. {packingcubes-0.2.3 → packingcubes-0.3.1}/README.md +0 -0
  55. {packingcubes-0.2.3 → packingcubes-0.3.1}/cliff.toml +0 -0
  56. {packingcubes-0.2.3/doc → packingcubes-0.3.1/docs}/example_packed.jpg +0 -0
  57. {packingcubes-0.2.3 → packingcubes-0.3.1}/examples/Basic_Usage.py +0 -0
  58. {packingcubes-0.2.3 → packingcubes-0.3.1}/examples/Example_PackedTree.py +0 -0
  59. {packingcubes-0.2.3 → packingcubes-0.3.1}/packingcubes/configuration.py +0 -0
  60. {packingcubes-0.2.3 → packingcubes-0.3.1}/packingcubes/octree.py +0 -0
  61. {packingcubes-0.2.3 → packingcubes-0.3.1}/packingcubes/packed_tree/__init__.py +0 -0
  62. {packingcubes-0.2.3 → packingcubes-0.3.1}/packingcubes/packed_tree/packed_tree_meta.py +0 -0
  63. {packingcubes-0.2.3 → packingcubes-0.3.1}/packingcubes/tree_vis.py +0 -0
  64. {packingcubes-0.2.3 → packingcubes-0.3.1}/packingcubes.egg-info/dependency_links.txt +0 -0
  65. {packingcubes-0.2.3 → packingcubes-0.3.1}/packingcubes.egg-info/requires.txt +0 -0
  66. {packingcubes-0.2.3 → packingcubes-0.3.1}/packingcubes.egg-info/top_level.txt +0 -0
  67. {packingcubes-0.2.3 → packingcubes-0.3.1}/setup.cfg +0 -0
  68. {packingcubes-0.2.3 → packingcubes-0.3.1}/tests/conftest.py +0 -0
  69. {packingcubes-0.2.3 → packingcubes-0.3.1}/tests/test_data_objects.py +0 -0
  70. {packingcubes-0.2.3 → packingcubes-0.3.1}/tests/test_octree.py +0 -0
@@ -25,7 +25,7 @@ jobs:
25
25
  steps:
26
26
  - uses: actions/checkout@v6
27
27
  - name: Install pixi and run tests
28
- uses: prefix-dev/setup-pixi@v0.9.4
28
+ uses: prefix-dev/setup-pixi@v0.9.5
29
29
  with:
30
30
  pixi-version: v0.66.0
31
31
  cache: true
@@ -0,0 +1,29 @@
1
+ name: Documentation
2
+ on:
3
+ push:
4
+ branches:
5
+ - master
6
+ - main
7
+ permissions:
8
+ contents: read
9
+ pages: write
10
+ id-token: write
11
+ jobs:
12
+ deploy:
13
+ environment:
14
+ name: github-pages
15
+ url: ${{ steps.deployment.outputs.page_url }}
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - uses: actions/configure-pages@v5
19
+ - uses: actions/checkout@v5
20
+ - uses: actions/setup-python@v5
21
+ with:
22
+ python-version: 3.x
23
+ - run: pip install zensical
24
+ - run: zensical build --clean
25
+ - uses: actions/upload-pages-artifact@v4
26
+ with:
27
+ path: site
28
+ - uses: actions/deploy-pages@v4
29
+ id: deployment
@@ -22,7 +22,7 @@ jobs:
22
22
  with:
23
23
  python-version: "3.x"
24
24
  - name: Install pixi
25
- uses: prefix-dev/setup-pixi@v0.9.4
25
+ uses: prefix-dev/setup-pixi@v0.9.5
26
26
  with:
27
27
  pixi-version: v0.66.0
28
28
  cache: true
@@ -0,0 +1,19 @@
1
+ version: 2
2
+
3
+ build:
4
+ os: ubuntu-24.04
5
+ tools:
6
+ python: latest
7
+ jobs:
8
+ create_environment:
9
+ - asdf plugin add pixi
10
+ - asdf install pixi latest
11
+ - asdf global pixi latest
12
+ install:
13
+ - pixi install -e docs
14
+ build:
15
+ html:
16
+ - zensical build
17
+ post_build:
18
+ - mkdir -p $READTHEDOCS_OUTPUT/html/
19
+ - cp --recursive site/* $READTHEDOCS_OUTPUT/html/
@@ -1,3 +1,126 @@
1
+ ## [0.3.1] - 2026-04-15
2
+
3
+ ### 🚀 Features
4
+
5
+ - Expose benchmarking scripts on install ([d9a53e2](https://github.com/astrosocket/packingcubes/commit/d9a53e2a65e627902e42fee8976af4ff336284cc))
6
+
7
+ ### 🐛 Bug Fixes
8
+
9
+ - Forgot to update exposed cube script path ([fe91cd6](https://github.com/astrosocket/packingcubes/commit/fe91cd665eca9a4a3782fca1459f65815a025f1b))
10
+ - Nthreads should be set inside function ([785dd10](https://github.com/astrosocket/packingcubes/commit/785dd10e0a29dd17fd996e470d831ca967d6613f))
11
+
12
+ ### 🚜 Refactor
13
+
14
+ - Remove old Benchmarking code ([11d1a7b](https://github.com/astrosocket/packingcubes/commit/11d1a7b1bb41ba56d0d8a74a99c777c6781a5879))
15
+ - No longer need search object bounding boxes ([5c3fdc5](https://github.com/astrosocket/packingcubes/commit/5c3fdc581047f107461bc8c8a7ca605856eeb36e))
16
+ - Adding new cubes module files ([4d071ec](https://github.com/astrosocket/packingcubes/commit/4d071ec3e09f226d12f3e54b5fa7022f4f90b859))
17
+ - Removing old cubes module ([629b134](https://github.com/astrosocket/packingcubes/commit/629b1340e911ce3706b47753dfe410de8d95660e))
18
+
19
+ ### 📚 Documentation
20
+
21
+ - Minor updates to packed_format for better rendering ([a0bd3f3](https://github.com/astrosocket/packingcubes/commit/a0bd3f311baa3ee725e6aa9a5ddf9c9b4f25acb0))
22
+ - Add basic readthedocs and zensical setup ([e7a8765](https://github.com/astrosocket/packingcubes/commit/e7a87655900c898f76f4c4d20839c2d4d01bf96a))
23
+ - Move from doc folder to docs folder ([7fef852](https://github.com/astrosocket/packingcubes/commit/7fef852672bf7e04f1a7070a325112e5dc66619c))
24
+
25
+ ### 🧪 Testing
26
+
27
+ - Increasing test deadline ([b2c148c](https://github.com/astrosocket/packingcubes/commit/b2c148c10f9328c7083aa601298fd735ce45946c))
28
+ - Major benchmarking overhaul ([d857c86](https://github.com/astrosocket/packingcubes/commit/d857c86e74f84b7d1beeeeaf91c1098f77b8abc4))
29
+ - Handle ints that are bigger than unit64, vectors ([16c081a](https://github.com/astrosocket/packingcubes/commit/16c081a999143e3256fead54766460d3ca477f5f))
30
+ - Add additional large integer test ([f504380](https://github.com/astrosocket/packingcubes/commit/f50438094591cc2aa418f4b42faad40650396d46))
31
+ - Fix floating point error in test ([f207ce6](https://github.com/astrosocket/packingcubes/commit/f207ce69e7632339eee2bf96f5f7a33b58cc7829))
32
+
33
+ ### ⚙️ Miscellaneous Tasks
34
+
35
+ - *(release)* Update Changelog ([da51d42](https://github.com/astrosocket/packingcubes/commit/da51d429a33a4b4b59f19baa67b9c0f688dffdf5))
36
+ ## [0.3.0] - 2026-04-07
37
+
38
+ ### 🚀 Features
39
+
40
+ - Switch to custom heap implementation ([0cabc92](https://github.com/astrosocket/packingcubes/commit/0cabc92a97eebd31b3d0172122f3f50dbcdbb850))
41
+ - Update Cubes API for get_closest_particles ([8f8627c](https://github.com/astrosocket/packingcubes/commit/8f8627c73d3b7bbab53f92839558996a7b91f884))
42
+ - Add get_closest_particles for Cubes ([234c1d7](https://github.com/astrosocket/packingcubes/commit/234c1d7984b36caaaa824bac3d24cb7f4f62e31b))
43
+ - Add clip_to_box method ([261933b](https://github.com/astrosocket/packingcubes/commit/261933b1fe3ca34d7a720b512714154c8bdb1092))
44
+ - Change slice handling to use slice lists ([85e8aa2](https://github.com/astrosocket/packingcubes/commit/85e8aa213d4aa483028c97f0555d55ecb3585e17))
45
+ - Expose save_dataset if Dataset passed to KDtree ([dcb735f](https://github.com/astrosocket/packingcubes/commit/dcb735fec2b989feb1e0335362a76a27fbabe5d6))
46
+ - Updated default workers argument and warning ([79c1d49](https://github.com/astrosocket/packingcubes/commit/79c1d49fdc4b350f3841084a845de5b1444c5cc5))
47
+ - Switch to using ParticleCubes as the backing search object ([9368f3f](https://github.com/astrosocket/packingcubes/commit/9368f3ffec410e27ccdebb18cff4524d41e31165))
48
+ - Add stubs for closest particle queries and index lists for cubes ([de36637](https://github.com/astrosocket/packingcubes/commit/de366370eac8a72a0d3dceea6191ae9abcfb5fe8))
49
+ - Add methods to get particle_index_lists ([6442a16](https://github.com/astrosocket/packingcubes/commit/6442a16e20486323ba23a43ba6fd12810de99c49))
50
+ - Add method to save ParticleCubes to file ([e2298ab](https://github.com/astrosocket/packingcubes/commit/e2298ab7ce3abd732ada9cb2294b99ee952094d4))
51
+ - Add method to get single ParticleCubes instance ([8eecee6](https://github.com/astrosocket/packingcubes/commit/8eecee65f72b0a8c81d92393641ecac5a5ebaeb7))
52
+ - Add _get_indices_in_shape, replace in _sphere, _box ([7f79f2b](https://github.com/astrosocket/packingcubes/commit/7f79f2b4fbaf182f2c04554196010c3f3c734a1f))
53
+ - Allow single string particle types when making cubes ([7b7bb19](https://github.com/astrosocket/packingcubes/commit/7b7bb1944aa9de10c304b3acd5aefc0f9594ebbe))
54
+ - Add a pass to remove empty cubes ([c1e2c2b](https://github.com/astrosocket/packingcubes/commit/c1e2c2b3a4ebab75aa98012c89d170607caca164))
55
+ - Add PackedTree __len__ as number of particles ([34c2c87](https://github.com/astrosocket/packingcubes/commit/34c2c87d2cf9f865baea0728a716318f39556f83))
56
+
57
+ ### 🐛 Bug Fixes
58
+
59
+ - Forgot to increase scale ([8c5bb15](https://github.com/astrosocket/packingcubes/commit/8c5bb150c2a6c9e98236b45392b2617cb8afdffc))
60
+ - Nodes were changing the tree box ([202cd07](https://github.com/astrosocket/packingcubes/commit/202cd07a5a2eab5e5ecebe426b9e3d749dd5523d))
61
+ - Handle passing None to particle_threshold ([3bd6629](https://github.com/astrosocket/packingcubes/commit/3bd6629bbf18689d61f0c8bb35bd7bbdf1b30b50))
62
+ - Some keys not populated yet in incremental saving ([b1ca1a5](https://github.com/astrosocket/packingcubes/commit/b1ca1a581b4ad70a2b6272a6b51675a6ed33e0d6))
63
+ - Add default value for number_balls ([22410d8](https://github.com/astrosocket/packingcubes/commit/22410d83eba5de2dd983135d8e10659b88c17f19))
64
+ - Bounding_box setup after position loading ([202e658](https://github.com/astrosocket/packingcubes/commit/202e6585b34d55ab3b41ea35588de34c18f9164c))
65
+ - Explicit type conversion, move objmode out of loop ([0f6fea0](https://github.com/astrosocket/packingcubes/commit/0f6fea057eaa6ed8d3643aabdeb755fc100bc991))
66
+ - ParticleCubes don't have particle_type, clean up warning ([cc3b6d8](https://github.com/astrosocket/packingcubes/commit/cc3b6d8bf434ff0db68994fd6c278ab9283bc198))
67
+ - Incorrect box sizes passed to tree construction ([520000f](https://github.com/astrosocket/packingcubes/commit/520000f14472ddc7b167d7c6c4d4b8a841111f90))
68
+ - More off-by-one errors ([1f74205](https://github.com/astrosocket/packingcubes/commit/1f742055978885617d03f2a3491f0cca4b045ad0))
69
+ - Actually sort in place ([0837807](https://github.com/astrosocket/packingcubes/commit/0837807541424b52c67725ac6625d80d5a125505))
70
+ - Leaf root nodes should still check partiality ([f08e3db](https://github.com/astrosocket/packingcubes/commit/f08e3dbd7899935fe61300d4be04748fac4dbc4d))
71
+ - Off-by-one error on node length ([c1af9e2](https://github.com/astrosocket/packingcubes/commit/c1af9e2432c89581f8182089c66648281ff1d407))
72
+ - Dumb off-by-one error ([870315f](https://github.com/astrosocket/packingcubes/commit/870315f78c65e43c5112a2833fbde35d3f3c36af))
73
+
74
+ ### 💼 Other
75
+
76
+ - Fix another parallel list index casting ([ed3f038](https://github.com/astrosocket/packingcubes/commit/ed3f0386cbc3883ec7e2b257dcfabf00654b8f0e))
77
+
78
+ ### 🚜 Refactor
79
+
80
+ - Move boxsize processing to separate function ([b32fd92](https://github.com/astrosocket/packingcubes/commit/b32fd92f54e8033579897b41b748e9026c913352))
81
+ - Make variable names more consistent ([5531354](https://github.com/astrosocket/packingcubes/commit/553135414765df435a84387862f060cd79d17930))
82
+ - Change Cubes class to MultiCubes, add factory functions ([01bc347](https://github.com/astrosocket/packingcubes/commit/01bc347f4644689f5d91f2d60873ad5a6740d8d8))
83
+ - Use self._get_indices_in_shape instead _get_indices_in_shape ([7cb35ba](https://github.com/astrosocket/packingcubes/commit/7cb35ba39329351bee1b3a42d6cfb3cf9484bccc))
84
+ - Remove _big_index_tuple type ([849cf90](https://github.com/astrosocket/packingcubes/commit/849cf9025b5b95b738eb08d11f6d875403c1bb3c))
85
+ - Change order of methods in file ([efe7069](https://github.com/astrosocket/packingcubes/commit/efe7069fce39337fcf56094ce253f3278f46d0e8))
86
+ - Change output from list to array ([cd7fd50](https://github.com/astrosocket/packingcubes/commit/cd7fd50ded41a942a47736754dba299e499b1df2))
87
+ - Remove unnecessary bounding_box ([6ac9a7c](https://github.com/astrosocket/packingcubes/commit/6ac9a7c780d18a936e57a66d4ba4a57ece8e0ab4))
88
+
89
+ ### 📚 Documentation
90
+
91
+ - Add query performance timings ([0201e7d](https://github.com/astrosocket/packingcubes/commit/0201e7dca67bbe898c84486a8cdcae85da9f081f))
92
+ - Formatting, update timings, switch to creation, improve scale plot ([3c5f347](https://github.com/astrosocket/packingcubes/commit/3c5f347fab42a2ad27cf11d1db30d04a9f0fe9b4))
93
+ - Fix description of workers in qbp ([732a599](https://github.com/astrosocket/packingcubes/commit/732a5994aa0674e965d0ea70f602e1e5b05bd121))
94
+ - Clean up _get_indices_in_shape ([083fafb](https://github.com/astrosocket/packingcubes/commit/083fafb13529e48b92e930f01df51e0adb843896))
95
+ - Add missed changelog addition ([c19cdc4](https://github.com/astrosocket/packingcubes/commit/c19cdc4a09f669c41725ad0a32c724bc739dcaa7))
96
+
97
+ ### ⚡ Performance
98
+
99
+ - Rework get_closest_particles to use min-heap ([54afcdd](https://github.com/astrosocket/packingcubes/commit/54afcddcb6937e649e5c74ec7061f3bc588e0dd5))
100
+ - Updated timings showing strong scaling ([1dcd768](https://github.com/astrosocket/packingcubes/commit/1dcd7686a8e66ffa5718bb8510c811eb22a5a2f8))
101
+ - Change query_ball_point defaults to performant values ([45b7521](https://github.com/astrosocket/packingcubes/commit/45b75214df4287a6e88fdcaba4ce2aa9bba45fc0))
102
+ - Subboxes should probably be safe ([0bb1aee](https://github.com/astrosocket/packingcubes/commit/0bb1aee130ae7038269fd673d330380b77b54e32))
103
+ - Skip extraneous function call ([723bf13](https://github.com/astrosocket/packingcubes/commit/723bf13103f88889135566669ff3d8aace32cac7))
104
+
105
+ ### 🎨 Styling
106
+
107
+ - Supress additional enumeration warning ([efac873](https://github.com/astrosocket/packingcubes/commit/efac8735d6e026b29b0f41cbee98169a00b997fd))
108
+ - Suppress complaint about enumerating for loops ([fef8c84](https://github.com/astrosocket/packingcubes/commit/fef8c842ef2cdf321eb6c3112293a3d81ce32c2f))
109
+
110
+ ### 🧪 Testing
111
+
112
+ - Update query test to use config k, return sorted ([7942f96](https://github.com/astrosocket/packingcubes/commit/7942f966ab3f7359156ebc94e88580cbfe6f1483))
113
+ - Add performance options for query timing ([e8831ee](https://github.com/astrosocket/packingcubes/commit/e8831ee6b17570be58212a69aec2b7c136248fca))
114
+ - Kdtree query tests are working again ([d4359e6](https://github.com/astrosocket/packingcubes/commit/d4359e603d294be4d954251c6bf1d6a4d6d489e0))
115
+ - Stop saving dataset changes, API updates, cube profile update ([eec90ae](https://github.com/astrosocket/packingcubes/commit/eec90ae616c7033fc00f3a2b21e14df49527b3b7))
116
+ - Switch to custom timer for search objects ([7a039b2](https://github.com/astrosocket/packingcubes/commit/7a039b287d54f7ee44c7b31ae539a67ffa9410f0))
117
+ - Update profiling notebook ([cfe673f](https://github.com/astrosocket/packingcubes/commit/cfe673ffb8636223781519b828c0a1544302e837))
118
+ - Update benchmarking data ([c5a47dd](https://github.com/astrosocket/packingcubes/commit/c5a47dd2c2ac77adbd8b635f0bea8323f1a9383f))
119
+ - Save output on every loop iteration for incremental results ([10571af](https://github.com/astrosocket/packingcubes/commit/10571aff35786399ba7a02b8f561c80a7be99904))
120
+ - Add extra debug information ([eee95a0](https://github.com/astrosocket/packingcubes/commit/eee95a0777908605eec6de387817d2aa0737526c))
121
+ - Use new slice lists to load chunks of dataset instead of striding ([a1be6db](https://github.com/astrosocket/packingcubes/commit/a1be6db72e50161608afd8a0f5946a7529fafb7e))
122
+ - Add test for just the numba search portion ([eb9f60e](https://github.com/astrosocket/packingcubes/commit/eb9f60e1b33c3676e99907d709420b2b96925b4b))
123
+ - Add custom scaling to tests ([e5c45d8](https://github.com/astrosocket/packingcubes/commit/e5c45d82929580f02ef67ec8f7cce6c607de9cb3))
1
124
  ## [0.2.3] - 2026-03-25
2
125
 
3
126
  ### 🚀 Features
@@ -46,6 +169,7 @@
46
169
 
47
170
  ### 🚀 Features
48
171
 
172
+ - Enhancements derived from updating the README ([#12](https://github.com/astrosocket/packingcubes/issues/12)) ([256877c](https://github.com/astrosocket/packingcubes/commit/256877c79eb08fcc1dc6ee54d138c1ad67687a45))
49
173
  - Flesh out the readme ([e757b45](https://github.com/astrosocket/packingcubes/commit/e757b4586b2c79fe11e2152f70019a567f367d01))
50
174
  - Support passing a regular array to Cubes constructor ([c59097b](https://github.com/astrosocket/packingcubes/commit/c59097b8eb844dda5be5510125b7b4c487e7c54c))
51
175
  - Allow loading cubes data from file ([d45b5d7](https://github.com/astrosocket/packingcubes/commit/d45b5d70ee30975a870f75ee6ee348e745fafa37))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: packingcubes
3
- Version: 0.2.3
3
+ Version: 0.3.1
4
4
  Summary: PackingCubes octree implementation for astro data
5
5
  Author: Michael Ryan
6
6
  Author-email: Josh Borrow <josh@joshborrow.com>
@@ -0,0 +1,6 @@
1
+ ---
2
+ icon: lucide/box
3
+ ---
4
+
5
+ --8<-- "README.md"
6
+
@@ -0,0 +1,24 @@
1
+ window.MathJax = {
2
+ tex: {
3
+ inlineMath: [["\\(", "\\)"]],
4
+ displayMath: [["\\[", "\\]"]],
5
+ processEscapes: true,
6
+ processEnvironments: true
7
+ },
8
+ options: {
9
+ ignoreHtmlClass: ".*|",
10
+ processHtmlClass: "arithmatex"
11
+ }
12
+ };
13
+
14
+ document$.subscribe(() => {
15
+ MathJax.startup.output.clearCache()
16
+ MathJax.typesetClear()
17
+ MathJax.texReset()
18
+ MathJax.typesetPromise()
19
+ })
20
+
21
+ component$.subscribe(({ ref }) => {
22
+ if (ref.classList.contains("md-annotation"))
23
+ MathJax.typesetPromise([ref])
24
+ })
@@ -1,6 +1,6 @@
1
1
  # Packed Format Design Specification
2
2
 
3
- Version 1.0.0
3
+ Version 1.0.1
4
4
 
5
5
  This file documents the format used to describe a PackedTree data structure.
6
6
 
@@ -13,7 +13,7 @@ The basic unit of the packed format is the `field`, currently defined as a
13
13
  and internally is stored as a numpy array of such.
14
14
 
15
15
 
16
- # Tree Metadata
16
+ ## Tree Metadata
17
17
 
18
18
  | Field | Bytes | Description |
19
19
  | ----- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
@@ -32,6 +32,7 @@ and internally is stored as a numpy array of such.
32
32
  | 35 | 140-143 | Particle threshold |
33
33
 
34
34
  Timestamp is currently computed via
35
+
35
36
  ```python
36
37
  # conversion to timestamp
37
38
  t = np.float64(datetime.datetime.now(tz=datetime.UTC).timestamp())
@@ -40,6 +41,7 @@ datetime.datetime.fromtimestamp(t, tz=datetime.UTC)
40
41
  ```
41
42
 
42
43
  For the checksum, use [xxhash's xxh3](https://pypi.org/project/xxhash/) (not part of the standard library):
44
+
43
45
  ```python
44
46
  from xxhash import xxh3_64_intdigest
45
47
 
@@ -47,9 +49,23 @@ checksum = xxh3_64_intdigest(packed_tree)
47
49
  ```
48
50
  This creates a uint64 checksum.
49
51
 
50
- # Tree Data Structure
52
+ ## Tree Data Structure
53
+
54
+ Essentially we can think of the tree structure as the equivalent of `numpy`'s
55
+ structured array, except in an octree structure as opposed to the linear array
56
+ structure. Thus, the bytes are organized such that all information for a node
57
+ (*including it's children!*) are together in sequential order.
58
+
59
+ The intent is to mimic the in-memory structure of a simple tree from a language
60
+ like C, where every child node pointer has been replaced by the actual bytes
61
+ of the child node.
62
+
63
+ Thus, the first few bytes correspond to data attached to the root node, the
64
+ next few bytes are the first child's data, followed by the first grandchild,
65
+ etc., in a pre-order depth-first traversal of the tree.
51
66
 
52
- ## Internal Node:
67
+
68
+ ### Internal Node:
53
69
 
54
70
  | skip_length | node_start | node_end | child_flag | my_index | level | unused | C0 | C1 | C5 | C6 | C7 | parent_offset |
55
71
  | ----------- | ---------- | -------- | ----------- | -------- | ----- | ------ | --- | --- | --- | --- | --- | ------------- |
@@ -58,13 +74,38 @@ This creates a uint64 checksum.
58
74
  | field 0 | field 1 | field 2 | field 3 | | | | * | * | * | * | * | field 4 |
59
75
 
60
76
  For the present case, `child_flag` would be 227 ($=2^0 + 2^1 + 2^5 + 2^6 + 2^7$). If all 5 nodes were leaves, then `skip_length`=30.
61
- ## Leaf Node:
77
+
78
+ ### Leaf Node:
62
79
  Size = 5 fields = 20 bytes
63
80
 
64
81
  | skip_length=20 | node_start | node_end | child_flag=0 | my_index | level | unused | parent_offset |
65
82
  | -------------- | ---------- | -------- | ------------ | -------- | ----- | ------ | ------------- |
66
83
  | uint32 | uint32 | uint32 | uint8 | uint8 | uint8 | uint8 | uint32 |
67
84
 
68
- ## Example:
85
+ ### Example:
69
86
  ![Example packed array implementation](example_packed.jpg)
70
87
  Here, $x_{s}$, $x_{e}$, and $x_{m}$ are the node_start, node_end, and metadata (child_flag, my_index, level, and empty) fields for node $x$. The starred nodes in the tree are the last sibling for each group of children.
88
+
89
+
90
+ <script id="MathJax-script" src="https://unpkg.com/mathjax@3/es5/tex-mml-chtml.js"></script>
91
+ <script>
92
+ window.MathJax = {
93
+ tex: {
94
+ inlineMath: [["\\(", "\\)"]],
95
+ displayMath: [["\\[", "\\]"]],
96
+ processEscapes: true,
97
+ processEnvironments: true
98
+ },
99
+ options: {
100
+ ignoreHtmlClass: ".*|",
101
+ processHtmlClass: "arithmatex"
102
+ }
103
+ };
104
+
105
+ document$.subscribe(() => {
106
+ MathJax.startup.output.clearCache()
107
+ MathJax.typesetClear()
108
+ MathJax.texReset()
109
+ MathJax.typesetPromise()
110
+ })
111
+ </script>
@@ -33,6 +33,7 @@
33
33
 
34
34
  # %%
35
35
  # %load_ext profila
36
+ # %load_ext pyinstrument
36
37
 
37
38
  from time import time # noqa: E402
38
39
 
@@ -73,12 +74,11 @@ tree.get_particle_indices_in_sphere(center=center, radius=radius)
73
74
  cubes = Cubes(
74
75
  dataset=ds,
75
76
  particle_types=["PartType0"],
77
+ save_dataset=False,
76
78
  )
77
79
 
78
80
  # %%
79
- cubes.get_particle_indices_in_sphere(
80
- particle_types="PartType0", center=center, radius=radius
81
- )
81
+ cubes.get_particle_indices_in_sphere(center=center, radius=radius)
82
82
 
83
83
  # %%
84
84
  kdtree = KDTree(
@@ -127,10 +127,13 @@ while (time() - start) < 30:
127
127
  # %%
128
128
  # %%profila
129
129
 
130
- cubes = Cubes(
131
- dataset=ds,
132
- particle_types="PartType0",
133
- )
130
+ start = time()
131
+ while (time() - start) < 30:
132
+ cubes = Cubes(
133
+ dataset=ds,
134
+ particle_types=["PartType0"],
135
+ save_dataset=False,
136
+ )
134
137
 
135
138
  # %% [markdown] jp-MarkdownHeadingCollapsed=true
136
139
  # ## Profile cubes search
@@ -190,11 +193,8 @@ while (time() - start) < 30:
190
193
  # %% [markdown]
191
194
  # # Python profiling
192
195
 
193
- # %%
194
- # %load_ext pyinstrument
195
-
196
196
  # %% [markdown]
197
- # ##
197
+ # ## KDTree (python)
198
198
 
199
199
  # %%
200
200
  kdtree = KDTree(
@@ -214,7 +214,47 @@ sph_box = sph.bounding_box
214
214
 
215
215
  start = time()
216
216
  while (time() - start) < 30:
217
- sph_inds = kdtree.query_ball_point(x=centers[0], r=radius)
217
+ sph_inds = kdtree.query_ball_point(
218
+ x=centers[0], r=radius, return_data_indices=True, return_lists=False
219
+ )
220
+
221
+ # %% [markdown]
222
+ # ## Packed (python)
223
+
224
+ # %%
225
+ tree = Optree(dataset=ds)
226
+ center = np.array([15000, 15000, 15000])
227
+ radius = 1000
228
+
229
+ # %% [markdown]
230
+ # ### Packed search
231
+
232
+ # %%
233
+ # %%pyinstrument
234
+
235
+ start = time()
236
+ while (time() - start) < 30:
237
+ sph_inds = tree.get_particle_indices_in_sphere(center=center, radius=radius)
238
+
239
+ # %% [markdown]
240
+ # ## Cubes
241
+
242
+ # %% [markdown]
243
+ # ### Cubes creation
244
+
245
+ # %%
246
+ # %%pyinstrument
247
+
248
+ start = time()
249
+ while (time() - start) < 30:
250
+ cubes = Cubes(
251
+ dataset=ds,
252
+ particle_types=["PartType0"],
253
+ save_dataset=False,
254
+ )
255
+
256
+ # %% [markdown]
257
+ # ### Cubes search
218
258
 
219
259
  # %%
220
260
 
@@ -1,8 +1,19 @@
1
1
  import logging
2
2
  from importlib.metadata import PackageNotFoundError, version
3
3
 
4
- from packingcubes.cubes import Cubes as Cubes
4
+ from packingcubes.cubes import (
5
+ Cubes as Cubes,
6
+ )
7
+ from packingcubes.cubes import (
8
+ MultiCubes as MultiCubes,
9
+ )
10
+ from packingcubes.cubes import (
11
+ ParticleCubes as ParticleCubes,
12
+ )
5
13
  from packingcubes.cubes import make_cubes as make_cubes
14
+ from packingcubes.cubes import (
15
+ make_ParticleCubes as make_ParticleCubes,
16
+ )
6
17
  from packingcubes.data_objects import (
7
18
  GadgetishHDF5Dataset as HDF5Dataset,
8
19
  )
@@ -24,6 +35,9 @@ __all__ = [
24
35
  "KDTree",
25
36
  "make_cubes",
26
37
  "Cubes",
38
+ "ParticleCubes",
39
+ "MultiCubes",
40
+ "make_ParticleCubes",
27
41
  "__version__",
28
42
  ]
29
43
 
@@ -462,7 +462,7 @@ class BoundingBox(BoundingVolume):
462
462
  in_box = np.empty((xyz.shape[0],), dtype=np.bool_)
463
463
  bx, by, bz, dx, dy, dz = self.box
464
464
  for i in range(xyz.shape[0]):
465
- x, y, z = xyz[i, 0:2]
465
+ x, y, z = xyz[i, 0:3]
466
466
  in_box[i] = (
467
467
  ((bx <= x) & (x <= bx + dx))
468
468
  & ((by <= y) & (y <= by + dy))
@@ -493,7 +493,7 @@ class BoundingBox(BoundingVolume):
493
493
  in_box = 0
494
494
  bx, by, bz, dx, dy, dz = self.box
495
495
  for i in range(xyz.shape[0]):
496
- x, y, z = xyz[i, 0:2]
496
+ x, y, z = xyz[i, 0:3]
497
497
  in_box += (
498
498
  ((bx <= x) & (x <= bx + dx))
499
499
  & ((by <= y) & (y <= by + dy))
@@ -592,6 +592,45 @@ class BoundingBox(BoundingVolume):
592
592
  cz = min(max(z, bz + jz), bz + dz - jz)
593
593
  return cx, cy, cz
594
594
 
595
+ def clip_to_box(self, obox: BoundingBox) -> int:
596
+ """
597
+ Clip this box so it entirely fits within obox
598
+
599
+ Note: this action is potentiall unsafe! We do no checking that the new
600
+ box is correct in terms of floating point precision.
601
+
602
+ Args:
603
+ obox: BoundingBox
604
+ The box to clip to
605
+
606
+ Returns:
607
+ Returns 0 if any of the dx terms are 0, 1 otherwise
608
+ """
609
+ # The algorithm is similar to project_point_on_box
610
+ x, y, z, dx, dy, dz = self.box
611
+ ox, oy, oz, odx, ody, odz = obox.box
612
+
613
+ x = min(max(x, ox), ox + odx)
614
+ y = min(max(y, oy), oy + ody)
615
+ z = min(max(z, oz), oz + odz)
616
+ xfar = min(max(x + dx, ox), ox + odx)
617
+ yfar = min(max(y + dy, oy), oy + ody)
618
+ zfar = min(max(z + dz, oz), oz + odz)
619
+
620
+ new_dx = xfar - x
621
+ new_dy = yfar - y
622
+ new_dz = zfar - z
623
+
624
+ if new_dx <= 0 or new_dy <= 0 or new_dz <= 0:
625
+ return 0
626
+ self.box[0] = x
627
+ self.box[3] = new_dx
628
+ self.box[1] = y
629
+ self.box[4] = new_dy
630
+ self.box[2] = z
631
+ self.box[5] = new_dz
632
+ return 1
633
+
595
634
  def check_box_overlap(self, obox: BoundingBox) -> int:
596
635
  """
597
636
  Return the "overlap" between this box and obox
@@ -614,13 +653,13 @@ class BoundingBox(BoundingVolume):
614
653
  # check if any overlap at all
615
654
  # pxyz = obox.project_point_on_box( our center)
616
655
  # overlap = self.contains(pxyz)
617
- x, y, z, odx, ody, odz = obox.box
656
+ ox, oy, oz, odx, ody, odz = obox.box
618
657
  mx, my, mz = self.midplane()
619
658
  bx, by, bz, dx, dy, dz = self.box
620
659
 
621
- cx = min(max(mx, x), x + odx)
622
- cy = min(max(my, y), y + ody)
623
- cz = min(max(mz, z), z + odz)
660
+ cx = min(max(mx, ox), ox + odx)
661
+ cy = min(max(my, oy), oy + ody)
662
+ cz = min(max(mz, oz), oz + odz)
624
663
 
625
664
  overlap = (
626
665
  ((bx <= cx) & (cx <= bx + dx))
@@ -632,12 +671,12 @@ class BoundingBox(BoundingVolume):
632
671
  return 0
633
672
 
634
673
  # check how many vertices are contained
635
- x0 = x
636
- x1 = x + odx
637
- y0 = y
638
- y1 = y + ody
639
- z0 = z
640
- z1 = z + odz
674
+ x0 = ox
675
+ x1 = ox + odx
676
+ y0 = oy
677
+ y1 = oy + ody
678
+ z0 = oz
679
+ z1 = oz + odz
641
680
 
642
681
  overlap = (
643
682
  ((bx <= x0) & (x0 <= bx + dx))
@@ -789,7 +828,7 @@ class BoundingSphere(BoundingVolume):
789
828
  cx, cy, cz = self.center
790
829
  in_sph = np.empty((xyz.shape[0],), dtype=np.bool_)
791
830
  for i in range(xyz.shape[0]):
792
- x, y, z = xyz[i, 0:2]
831
+ x, y, z = xyz[i, 0:3]
793
832
  in_sph[i] = (cx - x) ** 2 + (cy - y) ** 2 + (cz - z) ** 2 <= r2
794
833
  return in_sph
795
834
 
@@ -817,7 +856,7 @@ class BoundingSphere(BoundingVolume):
817
856
  r2 = self.radius * self.radius
818
857
  cx, cy, cz = self.center
819
858
  for i in range(xyz.shape[0]):
820
- x, y, z = xyz[i, 0:2]
859
+ x, y, z = xyz[i, 0:3]
821
860
  in_sph += (cx - x) ** 2 + (cy - y) ** 2 + (cz - z) ** 2 <= r2
822
861
  return in_sph
823
862
 
@@ -843,13 +882,13 @@ class BoundingSphere(BoundingVolume):
843
882
  # check if any overlap at all
844
883
  # pxyz = obox.project_point_on_box( our center)
845
884
  # overlap = self.contains(pxyz)
846
- x, y, z, odx, ody, odz = obox.box
885
+ ox, oy, oz, odx, ody, odz = obox.box
847
886
  cx, cy, cz = self.center
848
887
  r2 = self.radius * self.radius
849
888
 
850
- px = min(max(cx, x), x + odx)
851
- py = min(max(cy, y), y + ody)
852
- pz = min(max(cz, z), z + odz)
889
+ px = min(max(cx, ox), ox + odx)
890
+ py = min(max(cy, oy), oy + ody)
891
+ pz = min(max(cz, oz), oz + odz)
853
892
 
854
893
  overlap = (cx - px) ** 2 + (cy - py) ** 2 + (cz - pz) ** 2 <= r2
855
894
 
@@ -857,12 +896,12 @@ class BoundingSphere(BoundingVolume):
857
896
  return 0
858
897
 
859
898
  # check how many vertices are contained
860
- x0 = x
861
- x1 = x + odx
862
- y0 = y
863
- y1 = y + ody
864
- z0 = z
865
- z1 = z + odz
899
+ x0 = ox
900
+ x1 = ox + odx
901
+ y0 = oy
902
+ y1 = oy + ody
903
+ z0 = oz
904
+ z1 = oz + odz
866
905
 
867
906
  overlap = (cx - x0) ** 2 + (cy - y0) ** 2 + (cz - z0) ** 2 <= r2
868
907
 
@@ -0,0 +1,23 @@
1
+ from packingcubes.cubes.cubes_creation import (
2
+ Cubes as Cubes,
3
+ )
4
+ from packingcubes.cubes.cubes_creation import (
5
+ CubesError as CubesError,
6
+ )
7
+ from packingcubes.cubes.cubes_creation import (
8
+ make_cubes as make_cubes,
9
+ )
10
+ from packingcubes.cubes.cubes_creation import (
11
+ make_ParticleCubes as make_ParticleCubes,
12
+ )
13
+ from packingcubes.cubes.multi_cubes import MultiCubes as MultiCubes
14
+ from packingcubes.cubes.particle_cubes import ParticleCubes as ParticleCubes
15
+
16
+ __all__ = [
17
+ "Cubes",
18
+ "CubesError",
19
+ "make_cubes",
20
+ "make_ParticleCubes",
21
+ "MultiCubes",
22
+ "ParticleCubes",
23
+ ]