mergechannels 0.1.1__tar.gz → 0.2.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.

Potentially problematic release.


This version of mergechannels might be problematic. Click here for more details.

Files changed (180) hide show
  1. {mergechannels-0.1.1 → mergechannels-0.2.0}/.gitattributes +1 -1
  2. {mergechannels-0.1.1 → mergechannels-0.2.0}/.github/workflows/CI.yml +58 -32
  3. {mergechannels-0.1.1 → mergechannels-0.2.0}/.gitignore +5 -1
  4. mergechannels-0.2.0/.pre-commit-config.yaml +16 -0
  5. {mergechannels-0.1.1 → mergechannels-0.2.0}/Cargo.lock +8 -1
  6. {mergechannels-0.1.1 → mergechannels-0.2.0}/Cargo.toml +2 -1
  7. {mergechannels-0.1.1 → mergechannels-0.2.0}/LICENSE +1 -1
  8. {mergechannels-0.1.1 → mergechannels-0.2.0}/PKG-INFO +58 -25
  9. {mergechannels-0.1.1 → mergechannels-0.2.0}/README.md +51 -22
  10. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/builtin_luts/phase.lut +0 -1
  11. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/christ_luts/Turbo.lut +1 -1
  12. {mergechannels-0.1.1 → mergechannels-0.2.0}/pyproject.toml +18 -3
  13. {mergechannels-0.1.1 → mergechannels-0.2.0}/pytests/test_colorize.py +78 -11
  14. mergechannels-0.2.0/python/mergechannels/__init__.py +13 -0
  15. mergechannels-0.2.0/python/mergechannels/__init__.pyi +30 -0
  16. {mergechannels-0.1.1 → mergechannels-0.2.0}/python/mergechannels/_internal.py +27 -20
  17. mergechannels-0.2.0/ruff.toml +86 -0
  18. {mergechannels-0.1.1 → mergechannels-0.2.0}/scripts/convert_luts_to_txt.ijm +1 -1
  19. {mergechannels-0.1.1 → mergechannels-0.2.0}/scripts/populate_luts.py +22 -19
  20. {mergechannels-0.1.1 → mergechannels-0.2.0}/src/blend.rs +43 -8
  21. mergechannels-0.2.0/src/colorize.rs +397 -0
  22. mergechannels-0.2.0/src/interface.rs +239 -0
  23. mergechannels-0.2.0/src/lib.rs +15 -0
  24. mergechannels-0.2.0/tox.ini +11 -0
  25. mergechannels-0.2.0/uv.lock +877 -0
  26. mergechannels-0.1.1/assets/readme_images/camera_red-green.png +0 -3
  27. mergechannels-0.1.1/assets/readme_images/cells_multicolor.png +0 -3
  28. mergechannels-0.1.1/python/mergechannels/__init__.py +0 -13
  29. mergechannels-0.1.1/python/mergechannels/__init__.pyi +0 -27
  30. mergechannels-0.1.1/src/colorize.rs +0 -64
  31. mergechannels-0.1.1/src/interface.rs +0 -36
  32. mergechannels-0.1.1/src/lib.rs +0 -15
  33. mergechannels-0.1.1/test.ipynb +0 -101
  34. mergechannels-0.1.1/uv.lock +0 -48
  35. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/builtin_luts/16_colors.lut +0 -0
  36. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/builtin_luts/5_ramps.lut +0 -0
  37. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/builtin_luts/6_shades.lut +0 -0
  38. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/builtin_luts/Cyan Hot.lut +0 -0
  39. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/builtin_luts/Green Fire Blue.lut +0 -0
  40. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/builtin_luts/HiLo.lut +0 -0
  41. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/builtin_luts/ICA.lut +0 -0
  42. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/builtin_luts/ICA2.lut +0 -0
  43. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/builtin_luts/ICA3.lut +0 -0
  44. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/builtin_luts/Magenta Hot.lut +0 -0
  45. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/builtin_luts/Orange Hot.lut +0 -0
  46. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/builtin_luts/Rainbow RGB.lut +0 -0
  47. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/builtin_luts/Red Hot.lut +0 -0
  48. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/builtin_luts/Thermal.lut +0 -0
  49. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/builtin_luts/Yellow Hot.lut +0 -0
  50. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/builtin_luts/blue_orange_icb.lut +0 -0
  51. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/builtin_luts/brgbcmyw.lut +0 -0
  52. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/builtin_luts/cool.lut +0 -0
  53. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/builtin_luts/edges.lut +0 -0
  54. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/builtin_luts/gem.lut +0 -0
  55. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/builtin_luts/glasbey.lut +0 -0
  56. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/builtin_luts/glasbey_inverted.lut +0 -0
  57. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/builtin_luts/glasbey_on_dark.lut +0 -0
  58. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/builtin_luts/glow.lut +0 -0
  59. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/builtin_luts/mpl-inferno.lut +0 -0
  60. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/builtin_luts/mpl-magma.lut +0 -0
  61. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/builtin_luts/mpl-plasma.lut +0 -0
  62. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/builtin_luts/mpl-viridis.lut +0 -0
  63. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/builtin_luts/physics.lut +0 -0
  64. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/builtin_luts/royal.lut +0 -0
  65. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/builtin_luts/sepia.lut +0 -0
  66. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/builtin_luts/smart.lut +0 -0
  67. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/builtin_luts/thal.lut +0 -0
  68. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/builtin_luts/thallium.lut +0 -0
  69. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/builtin_luts/unionjack.lut +0 -0
  70. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/christ_luts/3color-BMR.lut +0 -0
  71. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/christ_luts/3color-CGY.lut +0 -0
  72. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/christ_luts/3color-RMB.lut +0 -0
  73. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/christ_luts/3color-YGC.lut +0 -0
  74. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/christ_luts/BOP blue.lut +0 -0
  75. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/christ_luts/BOP orange.lut +0 -0
  76. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/christ_luts/BOP purple.lut +0 -0
  77. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/christ_luts/I Blue.lut +0 -0
  78. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/christ_luts/I Bordeaux.lut +0 -0
  79. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/christ_luts/I Cyan.lut +0 -0
  80. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/christ_luts/I Forest.lut +0 -0
  81. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/christ_luts/I Green.lut +0 -0
  82. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/christ_luts/I Magenta.lut +0 -0
  83. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/christ_luts/I Purple.lut +0 -0
  84. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/christ_luts/I Red.lut +0 -0
  85. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/christ_luts/I Yellow.lut +0 -0
  86. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/christ_luts/NOTICE +0 -0
  87. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/christ_luts/OPF fresh.lut +0 -0
  88. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/christ_luts/OPF orange.lut +0 -0
  89. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/christ_luts/OPF purple.lut +0 -0
  90. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/16_colors.txt +0 -0
  91. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/3-3-2 RGB.txt +0 -0
  92. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/3color-BMR.txt +0 -0
  93. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/3color-CGY.txt +0 -0
  94. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/3color-RMB.txt +0 -0
  95. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/3color-YGC.txt +0 -0
  96. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/5_ramps.txt +0 -0
  97. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/6_shades.txt +0 -0
  98. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/BOP blue.txt +0 -0
  99. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/BOP orange.txt +0 -0
  100. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/BOP purple.txt +0 -0
  101. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/Blue.txt +0 -0
  102. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/Cyan Hot.txt +0 -0
  103. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/Cyan.txt +0 -0
  104. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/Fire.txt +0 -0
  105. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/Grays.txt +0 -0
  106. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/Green Fire Blue.txt +0 -0
  107. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/Green.txt +0 -0
  108. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/HiLo.txt +0 -0
  109. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/I Blue.txt +0 -0
  110. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/I Bordeaux.txt +0 -0
  111. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/I Cyan.txt +0 -0
  112. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/I Forest.txt +0 -0
  113. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/I Green.txt +0 -0
  114. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/I Magenta.txt +0 -0
  115. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/I Purple.txt +0 -0
  116. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/I Red.txt +0 -0
  117. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/I Yellow.txt +0 -0
  118. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/ICA.txt +0 -0
  119. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/ICA2.txt +0 -0
  120. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/ICA3.txt +0 -0
  121. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/Ice.txt +0 -0
  122. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/Magenta Hot.txt +0 -0
  123. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/Magenta.txt +0 -0
  124. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/OIMB1.txt +0 -0
  125. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/OIMB2.txt +0 -0
  126. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/OIMB3.txt +0 -0
  127. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/OPF fresh.txt +0 -0
  128. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/OPF orange.txt +0 -0
  129. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/OPF purple.txt +0 -0
  130. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/Orange Hot.txt +0 -0
  131. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/Rainbow RGB.txt +0 -0
  132. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/Red Hot.txt +0 -0
  133. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/Red%Green.txt +0 -0
  134. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/Red.txt +0 -0
  135. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/Spectrum.txt +0 -0
  136. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/Thermal.txt +0 -0
  137. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/Turbo.txt +0 -0
  138. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/Yellow Hot.txt +0 -0
  139. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/Yellow.txt +0 -0
  140. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/betterBlue.txt +0 -0
  141. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/betterCyan.txt +0 -0
  142. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/betterGreen.txt +0 -0
  143. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/betterOrange.txt +0 -0
  144. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/betterRed.txt +0 -0
  145. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/betterYellow.txt +0 -0
  146. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/blue_orange_icb.txt +0 -0
  147. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/brgbcmyw.txt +0 -0
  148. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/cool.txt +0 -0
  149. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/edges.txt +0 -0
  150. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/gem.txt +0 -0
  151. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/glasbey.txt +0 -0
  152. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/glasbey_inverted.txt +0 -0
  153. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/glasbey_on_dark.txt +0 -0
  154. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/glow.txt +0 -0
  155. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/mpl-inferno.txt +0 -0
  156. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/mpl-magma.txt +0 -0
  157. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/mpl-plasma.txt +0 -0
  158. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/mpl-viridis.txt +0 -0
  159. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/phase.txt +0 -0
  160. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/physics.txt +0 -0
  161. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/royal.txt +0 -0
  162. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/sepia.txt +0 -0
  163. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/smart.txt +0 -0
  164. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/thal.txt +0 -0
  165. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/thallium.txt +0 -0
  166. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/converted/unionjack.txt +0 -0
  167. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/zac_luts/OIMB1.lut +0 -0
  168. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/zac_luts/OIMB2.lut +0 -0
  169. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/zac_luts/OIMB3.lut +0 -0
  170. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/zac_luts/betterBlue.lut +0 -0
  171. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/zac_luts/betterCyan.lut +0 -0
  172. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/zac_luts/betterGreen.lut +0 -0
  173. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/zac_luts/betterOrange.lut +0 -0
  174. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/zac_luts/betterRed.lut +0 -0
  175. {mergechannels-0.1.1 → mergechannels-0.2.0}/assets/zac_luts/betterYellow.lut +0 -0
  176. {mergechannels-0.1.1 → mergechannels-0.2.0}/python/mergechannels/_blending.py +0 -0
  177. {mergechannels-0.1.1 → mergechannels-0.2.0}/python/mergechannels/_luts.py +0 -0
  178. {mergechannels-0.1.1 → mergechannels-0.2.0}/python/mergechannels/py.typed +0 -0
  179. {mergechannels-0.1.1 → mergechannels-0.2.0}/src/cmaps.rs +0 -0
  180. {mergechannels-0.1.1 → mergechannels-0.2.0}/src/normalize.rs +0 -0
@@ -4,4 +4,4 @@
4
4
  *.jpeg filter=lfs diff=lfs merge=lfs -text
5
5
  *.gif filter=lfs diff=lfs merge=lfs -text
6
6
  *.tif filter=lfs diff=lfs merge=lfs -text
7
- *.tiff filter=lfs diff=lfs merge=lfs -text
7
+ *.tiff filter=lfs diff=lfs merge=lfs -text
@@ -8,8 +8,7 @@ name: CI
8
8
  on:
9
9
  push:
10
10
  branches:
11
- - main
12
- - mvp
11
+ - '*'
13
12
  tags:
14
13
  - '*'
15
14
  pull_request:
@@ -24,50 +23,73 @@ jobs:
24
23
  runs-on: ubuntu-latest
25
24
  steps:
26
25
  - uses: actions/checkout@v4
27
-
26
+
28
27
  # Setup Rust toolchain
29
28
  - name: Install Rust stable
30
29
  uses: dtolnay/rust-toolchain@stable
31
30
  with:
32
31
  components: rustfmt, clippy
33
-
34
- # Run Rust format check
32
+
35
33
  - name: Check Rust formatting
36
34
  run: cargo fmt --all -- --check
37
-
38
- # Run Clippy
35
+
39
36
  - name: Run Clippy
40
37
  run: cargo clippy -- -D warnings
41
-
42
- # Run Cargo tests
38
+
43
39
  - name: Run Cargo tests
44
40
  run: cargo test
45
-
46
- # # Setup Python for testing
47
- # - uses: actions/setup-python@v5
48
- # with:
49
- # python-version: 3.x
50
-
51
- # Install UV
41
+
52
42
  - name: Install UV
53
43
  uses: astral-sh/setup-uv@v5
54
-
55
- # Create virtual environment and install the project
56
- - name: Create virtual environment and install
57
- run: |
58
- uv venv .venv --python 3.11
59
- source .venv/bin/activate
60
- pip install -e .
61
-
62
- # Run pytest
63
- - name: Run pytest
44
+ with:
45
+ enable-cache: true
46
+
47
+ - name: Install the project
48
+ run: uv sync --all-extras --dev
49
+
50
+ - name: Run pre-commit
51
+ shell: bash -l {0}
52
+ run: uv run pre-commit run --all-files
53
+
54
+ tox_tests:
55
+ name: Tox Tests (${{ matrix.python-version }}) # Add python version to name for clarity
56
+ runs-on: ubuntu-latest
57
+ strategy:
58
+ matrix:
59
+ python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
60
+ fail-fast: true # Optional: prevent other matrix jobs from cancelling if one fails
61
+ steps:
62
+ - uses: actions/checkout@v4
63
+
64
+ # Set up the specific Python version for this matrix job
65
+ - name: Set up Python ${{ matrix.python-version }}
66
+ uses: actions/setup-python@v5
67
+ with:
68
+ python-version: ${{ matrix.python-version }}
69
+
70
+ # Install UV using the official action, enabling caching
71
+ - name: Install UV
72
+ uses: astral-sh/setup-uv@v5
73
+ with:
74
+ # Enable uv's cache for faster subsequent runs
75
+ enable-cache: true
76
+
77
+ # Install tox and tox-uv using uv tool install
78
+ # This installs them into an isolated environment managed by uv
79
+ - name: Install Tox with tox-uv plugin using UV
80
+ run: uv tool install tox --with tox-uv
81
+
82
+ # Run Tox using uvx
83
+ # uvx ensures that the 'tox' command installed via 'uv tool install' is used
84
+ - name: Run Tox tests via uvx
64
85
  run: |
65
- source .venv/bin/activate
66
- pip install pytest
67
- pytest
86
+ PY_VERSION=$(echo ${{ matrix.python-version }} | tr -d '.')
87
+ uvx tox -e py$PY_VERSION
68
88
 
69
- linux:
70
- needs: rust_checks_and_python_tests
89
+
90
+ build:
91
+ needs: [rust_checks_and_python_tests, tox_tests]
92
+ if: ${{ startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' }}
71
93
  runs-on: ${{ matrix.platform.runner }}
72
94
  strategy:
73
95
  matrix:
@@ -104,6 +126,7 @@ jobs:
104
126
 
105
127
  musllinux:
106
128
  needs: rust_checks_and_python_tests
129
+ if: ${{ startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' }}
107
130
  runs-on: ${{ matrix.platform.runner }}
108
131
  strategy:
109
132
  matrix:
@@ -136,6 +159,7 @@ jobs:
136
159
 
137
160
  windows:
138
161
  needs: rust_checks_and_python_tests
162
+ if: ${{ startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' }}
139
163
  runs-on: ${{ matrix.platform.runner }}
140
164
  strategy:
141
165
  matrix:
@@ -164,6 +188,7 @@ jobs:
164
188
 
165
189
  macos:
166
190
  needs: rust_checks_and_python_tests
191
+ if: ${{ startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' }}
167
192
  runs-on: ${{ matrix.platform.runner }}
168
193
  strategy:
169
194
  matrix:
@@ -191,6 +216,7 @@ jobs:
191
216
 
192
217
  sdist:
193
218
  needs: rust_checks_and_python_tests
219
+ if: ${{ startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' }}
194
220
  runs-on: ubuntu-latest
195
221
  steps:
196
222
  - uses: actions/checkout@v4
@@ -209,7 +235,7 @@ jobs:
209
235
  name: Release
210
236
  runs-on: ubuntu-latest
211
237
  if: ${{ startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' }}
212
- needs: [linux, musllinux, windows, macos, sdist]
238
+ needs: [build, musllinux, windows, macos, sdist]
213
239
  permissions:
214
240
  # Use to sign the release artifacts
215
241
  id-token: write
@@ -72,4 +72,8 @@ docs/_build/
72
72
  .python-version
73
73
 
74
74
  # ignore images
75
- *.tif*
75
+ *.tif*
76
+
77
+ # ignore notebooks
78
+ *.ipynb
79
+ *.ju.py
@@ -0,0 +1,16 @@
1
+ repos:
2
+ - repo: https://github.com/pre-commit/pre-commit-hooks
3
+ rev: v4.6.0
4
+ hooks:
5
+ - id: trailing-whitespace
6
+ - id: end-of-file-fixer
7
+ - id: check-yaml
8
+ - id: check-toml
9
+ - id: check-added-large-files
10
+
11
+ - repo: https://github.com/astral-sh/ruff-pre-commit
12
+ rev: v0.3.3
13
+ hooks:
14
+ - id: ruff
15
+ types_or: [ python, pyi, jupyter ]
16
+ args: [ --fix ]
@@ -59,12 +59,13 @@ dependencies = [
59
59
 
60
60
  [[package]]
61
61
  name = "mergechannels"
62
- version = "0.1.1"
62
+ version = "0.2.0"
63
63
  dependencies = [
64
64
  "lazy_static",
65
65
  "ndarray",
66
66
  "numpy",
67
67
  "pyo3",
68
+ "smallvec",
68
69
  ]
69
70
 
70
71
  [[package]]
@@ -239,6 +240,12 @@ version = "2.1.1"
239
240
  source = "registry+https://github.com/rust-lang/crates.io-index"
240
241
  checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
241
242
 
243
+ [[package]]
244
+ name = "smallvec"
245
+ version = "1.15.0"
246
+ source = "registry+https://github.com/rust-lang/crates.io-index"
247
+ checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9"
248
+
242
249
  [[package]]
243
250
  name = "syn"
244
251
  version = "2.0.98"
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "mergechannels"
3
- version = "0.1.1"
3
+ version = "0.2.0"
4
4
  edition = "2021"
5
5
 
6
6
  # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -13,3 +13,4 @@ lazy_static = "1.5.0"
13
13
  ndarray = "0.16.1"
14
14
  numpy = "0.24.0"
15
15
  pyo3 = "0.24.1"
16
+ smallvec = "1.15.0"
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
18
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
21
+ SOFTWARE.
@@ -1,24 +1,28 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mergechannels
3
- Version: 0.1.1
3
+ Version: 0.2.0
4
4
  Classifier: Programming Language :: Rust
5
5
  Classifier: Programming Language :: Python :: Implementation :: CPython
6
6
  Classifier: Programming Language :: Python :: Implementation :: PyPy
7
7
  Classifier: License :: OSI Approved :: MIT License
8
8
  Classifier: Programming Language :: Python :: 3
9
- Classifier: Programming Language :: Python :: 3.8
10
9
  Classifier: Programming Language :: Python :: 3.9
11
10
  Classifier: Programming Language :: Python :: 3.10
12
11
  Classifier: Programming Language :: Python :: 3.11
13
12
  Classifier: Programming Language :: Python :: 3.12
14
- Requires-Dist: numpy>=1.24.4
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Requires-Dist: numpy>1.25.0
15
+ Provides-Extra: nvim
15
16
  License-File: LICENSE
17
+ Summary: Apply and merge colormaps
18
+ Author-email: Zac Swider <zac.swider@gmail.com>
16
19
  License: MIT
17
- Requires-Python: >=3.8, <3.13
20
+ Requires-Python: >=3.9, <=3.13
18
21
  Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
19
22
 
20
23
  [![CI](https://github.com/zacswider/mergechannels/actions/workflows/CI.yml/badge.svg)](https://github.com/zacswider/mergechannels/actions/workflows/CI.yml)
21
- ![License](https://img.shields.io/badge/license-MIT-blue.svg)
24
+ ![PyPI - License](https://img.shields.io/pypi/l/mergechannels)
25
+ ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/mergechannels)
22
26
  ![PyPI](https://img.shields.io/pypi/v/mergechannels)
23
27
 
24
28
  # mergechannels
@@ -59,7 +63,7 @@ plt.show()
59
63
  print(colorized.shape, colorized.dtype)
60
64
  >> (512, 512, 3) uint8
61
65
  ```
62
- ![colorize a single image](assets/readme_images/camera_red-green.png)
66
+ ![colorize a single image](https://raw.githubusercontent.com/zacswider/README_Images/main/camera_red-green.png)
63
67
 
64
68
 
65
69
  ### apply a different colormap to each channel
@@ -69,38 +73,66 @@ import matplotlib.pyplot as plt
69
73
  import mergechannels as mc
70
74
 
71
75
  cells, nuclei = data.cells3d().max(axis=0)
72
- cells = to_uint8(cells) # normalize your own arrays, mergechannels doesn't currently handle this
73
- nuclei = to_uint8(nuclei) # normalize your own arrays, mergechannels doesn't currently handle this
76
+ assert cells.dtype == 'uint16' and nuclei.dtype == 'uint16'
77
+ fig, axes = plt.subplots(1, 2, figsize=(3, 6), dpi=300)
78
+ for ax in axes.ravel(): ax.axis('off')
79
+ (a, b) = axes.ravel()
80
+ a.imshow(mc.merge([cells, nuclei],['Orange Hot', 'Cyan Hot']))
81
+ b.imshow(mc.merge([cells, nuclei],['I Blue', 'I Forest'], blending='min'))
82
+ fig.tight_layout()
83
+ plt.show()
84
+ ```
85
+ ![max and min multicolor blending](https://raw.githubusercontent.com/zacswider/README_Images/main/overlay_normal_and_inverted.png)
86
+
87
+ ### apply a colormap to a whole stack
88
+ ```python
89
+ from skimage import data
90
+ from matplotlib import pyplot as plt
91
+ import mergechannels as mc
92
+
93
+ volume = data.cells3d()
94
+ cells = volume[:, 0]
95
+ nuclei = volume[:, 1]
96
+ merged = mc.merge([cells, nuclei],['Orange Hot', 'Cyan Hot'])
97
+ plt.imshow(merged[24]); plt.show()
98
+ ```
99
+ ![colorize a whole stack of images](https://raw.githubusercontent.com/zacswider/README_Images/main/merged_stacks.png)
74
100
 
75
- fig, axes = plt.subplots(2, 2, figsize=(6, 6), dpi=150)
101
+ ### adjust the saturation limits when applying colormaps
102
+ ``` python
103
+ from skimage import data
104
+ import matplotlib.pyplot as plt
105
+ import mergechannels as mc
106
+
107
+ cells, nuclei = data.cells3d().max(axis=0)
108
+ channels = [cells, nuclei]
109
+ colormaps = ['I Blue', 'I Forest']
110
+ fig, axes = plt.subplots(1, 2, figsize=(3, 6), dpi=300)
76
111
  for ax in axes.ravel(): ax.axis('off')
77
- (a, b, c, d) = axes.ravel()
78
- a.imshow(cells, cmap='gray')
79
- b.imshow(nuclei, cmap='gray')
80
- c.imshow(
112
+ (a, b) = axes.ravel()
113
+ a.imshow(mc.merge(channels, colormaps, blending='min'))
114
+ b.imshow(
81
115
  mc.merge(
82
- [cells, nuclei],
83
- ['Orange Hot', 'Cyan Hot'], # maximum blending is the default
84
- ),
85
- )
86
- d.imshow(
87
- mc.merge(
88
- [cells, nuclei],
89
- ['I Blue', 'I Forest'],
90
- blending='min', # use minimum blending with inverted colormaps
116
+ channels,
117
+ colormaps,
118
+ blending='min',
119
+ saturation_limits=(
120
+ 0.01, # bottom 1% of pixels set to black point
121
+ 0.97, # top 3% of pixels set to white point
122
+ ),
91
123
  ),
92
124
  )
93
125
  fig.tight_layout()
94
126
  plt.show()
95
127
  ```
96
- ![apply a different colormap to each channel](assets/readme_images/cells_multicolor.png)
128
+ ![adjust saturation limits](https://raw.githubusercontent.com/zacswider/README_Images/main/adjust_sat_lims.png)
97
129
 
98
130
 
99
131
  ## Roadmap
100
- mergechannels is currently incredibly simple. It can apply one or more colormaps to one or more 2D 8-bit images and that's it.
132
+ mergechannels is currently incredibly simple. It can apply one or more colormaps to one or more 2D and 3D 8-bit or 16-bit images and that's it.
101
133
  - Add support for any numerical dtype
102
- - Add support for 3D images
103
134
  - Add option to return any colormap as a matplotlib colormap
135
+ - Add option to pass external colormaps to mergechannels
104
136
  - Add support for directly passing matplotlib colormaps instead of colormap names
105
137
  - Parallelize colormap application on large images (if it's helpful)
106
138
  - Add option to overlay binary or instance masks onto colorized images
@@ -110,3 +142,4 @@ mergechannels is currently incredibly simple. It can apply one or more colormaps
110
142
  There are other great colormapping libraries available (e.g., [microfilm](https://github.com/guiwitz/microfilm), [cmap](https://github.com/pyapp-kit/cmap)) that are more feature-rich than this one, but which don't address my goals. My hope is that this project can fill an un-met niche and otherwise maintain full compatibility with these and similar libraries.
111
143
 
112
144
  This project incorporates a number of colormaps that were hand-crafted by Christophe Leterrier and were originally distributed here under the MIT license: https://github.com/cleterrier/ChrisLUTs
145
+
@@ -1,5 +1,6 @@
1
1
  [![CI](https://github.com/zacswider/mergechannels/actions/workflows/CI.yml/badge.svg)](https://github.com/zacswider/mergechannels/actions/workflows/CI.yml)
2
- ![License](https://img.shields.io/badge/license-MIT-blue.svg)
2
+ ![PyPI - License](https://img.shields.io/pypi/l/mergechannels)
3
+ ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/mergechannels)
3
4
  ![PyPI](https://img.shields.io/pypi/v/mergechannels)
4
5
 
5
6
  # mergechannels
@@ -40,7 +41,7 @@ plt.show()
40
41
  print(colorized.shape, colorized.dtype)
41
42
  >> (512, 512, 3) uint8
42
43
  ```
43
- ![colorize a single image](assets/readme_images/camera_red-green.png)
44
+ ![colorize a single image](https://raw.githubusercontent.com/zacswider/README_Images/main/camera_red-green.png)
44
45
 
45
46
 
46
47
  ### apply a different colormap to each channel
@@ -50,38 +51,66 @@ import matplotlib.pyplot as plt
50
51
  import mergechannels as mc
51
52
 
52
53
  cells, nuclei = data.cells3d().max(axis=0)
53
- cells = to_uint8(cells) # normalize your own arrays, mergechannels doesn't currently handle this
54
- nuclei = to_uint8(nuclei) # normalize your own arrays, mergechannels doesn't currently handle this
54
+ assert cells.dtype == 'uint16' and nuclei.dtype == 'uint16'
55
+ fig, axes = plt.subplots(1, 2, figsize=(3, 6), dpi=300)
56
+ for ax in axes.ravel(): ax.axis('off')
57
+ (a, b) = axes.ravel()
58
+ a.imshow(mc.merge([cells, nuclei],['Orange Hot', 'Cyan Hot']))
59
+ b.imshow(mc.merge([cells, nuclei],['I Blue', 'I Forest'], blending='min'))
60
+ fig.tight_layout()
61
+ plt.show()
62
+ ```
63
+ ![max and min multicolor blending](https://raw.githubusercontent.com/zacswider/README_Images/main/overlay_normal_and_inverted.png)
64
+
65
+ ### apply a colormap to a whole stack
66
+ ```python
67
+ from skimage import data
68
+ from matplotlib import pyplot as plt
69
+ import mergechannels as mc
70
+
71
+ volume = data.cells3d()
72
+ cells = volume[:, 0]
73
+ nuclei = volume[:, 1]
74
+ merged = mc.merge([cells, nuclei],['Orange Hot', 'Cyan Hot'])
75
+ plt.imshow(merged[24]); plt.show()
76
+ ```
77
+ ![colorize a whole stack of images](https://raw.githubusercontent.com/zacswider/README_Images/main/merged_stacks.png)
78
+
79
+ ### adjust the saturation limits when applying colormaps
80
+ ``` python
81
+ from skimage import data
82
+ import matplotlib.pyplot as plt
83
+ import mergechannels as mc
55
84
 
56
- fig, axes = plt.subplots(2, 2, figsize=(6, 6), dpi=150)
85
+ cells, nuclei = data.cells3d().max(axis=0)
86
+ channels = [cells, nuclei]
87
+ colormaps = ['I Blue', 'I Forest']
88
+ fig, axes = plt.subplots(1, 2, figsize=(3, 6), dpi=300)
57
89
  for ax in axes.ravel(): ax.axis('off')
58
- (a, b, c, d) = axes.ravel()
59
- a.imshow(cells, cmap='gray')
60
- b.imshow(nuclei, cmap='gray')
61
- c.imshow(
62
- mc.merge(
63
- [cells, nuclei],
64
- ['Orange Hot', 'Cyan Hot'], # maximum blending is the default
65
- ),
66
- )
67
- d.imshow(
90
+ (a, b) = axes.ravel()
91
+ a.imshow(mc.merge(channels, colormaps, blending='min'))
92
+ b.imshow(
68
93
  mc.merge(
69
- [cells, nuclei],
70
- ['I Blue', 'I Forest'],
71
- blending='min', # use minimum blending with inverted colormaps
94
+ channels,
95
+ colormaps,
96
+ blending='min',
97
+ saturation_limits=(
98
+ 0.01, # bottom 1% of pixels set to black point
99
+ 0.97, # top 3% of pixels set to white point
100
+ ),
72
101
  ),
73
102
  )
74
103
  fig.tight_layout()
75
104
  plt.show()
76
105
  ```
77
- ![apply a different colormap to each channel](assets/readme_images/cells_multicolor.png)
106
+ ![adjust saturation limits](https://raw.githubusercontent.com/zacswider/README_Images/main/adjust_sat_lims.png)
78
107
 
79
108
 
80
109
  ## Roadmap
81
- mergechannels is currently incredibly simple. It can apply one or more colormaps to one or more 2D 8-bit images and that's it.
110
+ mergechannels is currently incredibly simple. It can apply one or more colormaps to one or more 2D and 3D 8-bit or 16-bit images and that's it.
82
111
  - Add support for any numerical dtype
83
- - Add support for 3D images
84
112
  - Add option to return any colormap as a matplotlib colormap
113
+ - Add option to pass external colormaps to mergechannels
85
114
  - Add support for directly passing matplotlib colormaps instead of colormap names
86
115
  - Parallelize colormap application on large images (if it's helpful)
87
116
  - Add option to overlay binary or instance masks onto colorized images
@@ -90,4 +119,4 @@ mergechannels is currently incredibly simple. It can apply one or more colormaps
90
119
 
91
120
  There are other great colormapping libraries available (e.g., [microfilm](https://github.com/guiwitz/microfilm), [cmap](https://github.com/pyapp-kit/cmap)) that are more feature-rich than this one, but which don't address my goals. My hope is that this project can fill an un-met niche and otherwise maintain full compatibility with these and similar libraries.
92
121
 
93
- This project incorporates a number of colormaps that were hand-crafted by Christophe Leterrier and were originally distributed here under the MIT license: https://github.com/cleterrier/ChrisLUTs
122
+ This project incorporates a number of colormaps that were hand-crafted by Christophe Leterrier and were originally distributed here under the MIT license: https://github.com/cleterrier/ChrisLUTs
@@ -254,4 +254,4 @@ Index Red Green Blue
254
254
  252 133 7 2
255
255
  253 129 6 2
256
256
  254 126 5 2
257
- 255 122 4 3
257
+ 255 122 4 3
@@ -4,22 +4,37 @@ build-backend = "maturin"
4
4
 
5
5
  [project]
6
6
  name = "mergechannels"
7
+ description = "Apply and merge colormaps"
8
+ readme = "README.md"
9
+ authors = [{ name = "Zac Swider", email = "zac.swider@gmail.com" }]
7
10
  license = { text = "MIT" }
8
- requires-python = ">=3.8, <3.13"
11
+ requires-python = ">=3.9, <=3.13"
9
12
  classifiers = [
10
13
  "Programming Language :: Rust",
11
14
  "Programming Language :: Python :: Implementation :: CPython",
12
15
  "Programming Language :: Python :: Implementation :: PyPy",
13
16
  "License :: OSI Approved :: MIT License",
14
17
  "Programming Language :: Python :: 3",
15
- "Programming Language :: Python :: 3.8",
16
18
  "Programming Language :: Python :: 3.9",
17
19
  "Programming Language :: Python :: 3.10",
18
20
  "Programming Language :: Python :: 3.11",
19
21
  "Programming Language :: Python :: 3.12",
22
+ "Programming Language :: Python :: 3.13",
20
23
  ]
21
24
  dynamic = ["version"]
22
- dependencies = ["numpy>=1.24.4"]
25
+ dependencies = ["numpy>1.25.0"]
26
+
27
+ [project.optional-dependencies]
28
+ nvim = []
23
29
  [tool.maturin]
24
30
  features = ["pyo3/extension-module"]
25
31
  python-source = "python"
32
+
33
+ [dependency-groups]
34
+ dev = [
35
+ "matplotlib>=3.7.5",
36
+ "pre-commit>=3.5.0",
37
+ "pynvim>=0.5.2",
38
+ "pytest-benchmark>=4.0.0",
39
+ "pytest>=8.3.5",
40
+ ]