bonesistools 1.2.8__tar.gz → 1.3.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 (199) hide show
  1. {bonesistools-1.2.8 → bonesistools-1.3.0}/PKG-INFO +1 -1
  2. {bonesistools-1.2.8 → bonesistools-1.3.0}/pyproject.toml +1 -1
  3. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/datasets/_geo.py +19 -6
  4. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/datasets/_registry.py +85 -3
  5. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/datasets/datasets.json +1 -1
  6. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/plotting/_barplot.py +175 -147
  7. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/plotting/_density.py +19 -52
  8. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/plotting/_distribution.py +1292 -1253
  9. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/plotting/_graph.py +3 -7
  10. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/plotting/_scatterplot.py +627 -653
  11. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/plotting/_utils.py +71 -2
  12. bonesistools-1.3.0/src/bonesistools/sctools/preprocessing/_hvg.py +1176 -0
  13. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/preprocessing/_qc.py +39 -38
  14. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/preprocessing/_transform.py +85 -33
  15. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/tools/_neighbors.py +31 -7
  16. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/tools/_stats.py +97 -80
  17. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/golden/README.md +10 -1
  18. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/golden/_workflow.py +62 -0
  19. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/golden/conftest.py +9 -1
  20. bonesistools-1.3.0/tests/golden/expected/hvg_binning.npz +0 -0
  21. bonesistools-1.3.0/tests/golden/expected/spectral.npz +0 -0
  22. bonesistools-1.3.0/tests/golden/expected/tsne.npz +0 -0
  23. bonesistools-1.3.0/tests/golden/expected/umap.npz +0 -0
  24. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/golden/test_golden_workflow.py +8 -0
  25. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/bpy/test_boolean_algebra.py +38 -0
  26. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/sct/datasets/test_geo.py +286 -0
  27. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/sct/datasets/test_nestorowa.py +18 -0
  28. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/sct/datasets/test_registry.py +36 -1
  29. bonesistools-1.3.0/tests/regression/sct/plotting/test_plotting_utils.py +212 -0
  30. bonesistools-1.3.0/tests/regression/sct/preprocessing/test_hvg.py +861 -0
  31. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/sct/preprocessing/test_qc.py +58 -0
  32. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/sct/preprocessing/test_simple.py +46 -0
  33. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/sct/tools/test_neighbors.py +118 -0
  34. bonesistools-1.3.0/tests/regression/test_import.py +77 -0
  35. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/reproducibility/test_reproducibility_workflow.py +21 -0
  36. bonesistools-1.2.8/src/bonesistools/sctools/preprocessing/_hvg.py +0 -407
  37. bonesistools-1.2.8/tests/regression/sct/preprocessing/test_hvg.py +0 -240
  38. bonesistools-1.2.8/tests/regression/test_import.py +0 -24
  39. {bonesistools-1.2.8 → bonesistools-1.3.0}/.gitignore +0 -0
  40. {bonesistools-1.2.8 → bonesistools-1.3.0}/LICENSE +0 -0
  41. {bonesistools-1.2.8 → bonesistools-1.3.0}/README.md +0 -0
  42. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/__init__.py +0 -0
  43. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/_compat.py +0 -0
  44. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/_metadata.py +0 -0
  45. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/_typing.py +0 -0
  46. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/_validation.py +0 -0
  47. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/_warnings.py +0 -0
  48. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/boolpy/__init__.py +0 -0
  49. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/boolpy/boolean_algebra/__init__.py +0 -0
  50. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/boolpy/boolean_algebra/_algebra.py +0 -0
  51. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/boolpy/boolean_algebra/_boolean.py +0 -0
  52. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/boolpy/boolean_algebra/_hypercube.py +0 -0
  53. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/boolpy/boolean_algebra/_kleene.py +0 -0
  54. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/boolpy/boolean_algebra/_parser.py +0 -0
  55. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/boolpy/boolean_algebra/_representation.py +0 -0
  56. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/boolpy/boolean_algebra/_structure.py +0 -0
  57. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/boolpy/boolean_algebra/_typing.py +0 -0
  58. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/boolpy/boolean_network/__init__.py +0 -0
  59. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/boolpy/boolean_network/_network.py +0 -0
  60. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/boolpy/boolean_network/_parser.py +0 -0
  61. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/boolpy/boolean_network/_typing.py +0 -0
  62. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/boolpy/influence_graph/__init__.py +0 -0
  63. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/boolpy/influence_graph/_algorithms.py +0 -0
  64. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/boolpy/influence_graph/_distances.py +0 -0
  65. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/boolpy/influence_graph/_influence_graph.py +0 -0
  66. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/boolpy/influence_graph/_parser.py +0 -0
  67. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/boolpy/influence_graph/_scoring.py +0 -0
  68. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/boolpy/influence_graph/_typing.py +0 -0
  69. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/boolpy/plotting/__init__.py +0 -0
  70. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/boolpy/plotting/_graphviz.py +0 -0
  71. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/boolpy/plotting/_styles.py +0 -0
  72. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/boolpy/plotting/_svg.py +0 -0
  73. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/databases/__init__.py +0 -0
  74. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/databases/hcop/__init__.py +0 -0
  75. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/databases/hcop/_orthologs.py +0 -0
  76. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/databases/hcop/data/human_anole_lizard_hcop.tsv.gz +0 -0
  77. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/databases/hcop/data/human_c.elegans_hcop.tsv.gz +0 -0
  78. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/databases/hcop/data/human_cat_hcop.tsv.gz +0 -0
  79. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/databases/hcop/data/human_cattle_hcop.tsv.gz +0 -0
  80. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/databases/hcop/data/human_chicken_hcop.tsv.gz +0 -0
  81. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/databases/hcop/data/human_chimpanzee_hcop.tsv.gz +0 -0
  82. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/databases/hcop/data/human_dog_hcop.tsv.gz +0 -0
  83. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/databases/hcop/data/human_fruitfly_hcop.tsv.gz +0 -0
  84. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/databases/hcop/data/human_horse_hcop.tsv.gz +0 -0
  85. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/databases/hcop/data/human_macaque_hcop.tsv.gz +0 -0
  86. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/databases/hcop/data/human_mouse_hcop.tsv.gz +0 -0
  87. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/databases/hcop/data/human_opossum_hcop.tsv.gz +0 -0
  88. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/databases/hcop/data/human_pig_hcop.tsv.gz +0 -0
  89. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/databases/hcop/data/human_platypus_hcop.tsv.gz +0 -0
  90. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/databases/hcop/data/human_rat_hcop.tsv.gz +0 -0
  91. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/databases/hcop/data/human_s.cerevisiae_hcop.tsv.gz +0 -0
  92. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/databases/hcop/data/human_s.pombe_hcop.tsv.gz +0 -0
  93. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/databases/hcop/data/human_xenopus_hcop.tsv.gz +0 -0
  94. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/databases/hcop/data/human_zebrafish_hcop.tsv.gz +0 -0
  95. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/databases/ncbi/__init__.py +0 -0
  96. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/databases/ncbi/_genesyn.py +0 -0
  97. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/databases/ncbi/_typing.py +0 -0
  98. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/databases/ncbi/data/gi/escherichia_coli_gene_info.tsv.gz +0 -0
  99. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/databases/ncbi/data/gi/homo_sapiens_gene_info.tsv.gz +0 -0
  100. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/databases/ncbi/data/gi/mus_musculus_gene_info.tsv.gz +0 -0
  101. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/databases/omnipath/__init__.py +0 -0
  102. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/databases/omnipath/_archive.py +0 -0
  103. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/databases/omnipath/_collectri.py +0 -0
  104. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/databases/omnipath/_dorothea.py +0 -0
  105. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/py.typed +0 -0
  106. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/__init__.py +0 -0
  107. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/_dependencies.py +0 -0
  108. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/_metadata.py +0 -0
  109. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/_stats.py +0 -0
  110. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/_typing.py +0 -0
  111. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/_validation.py +0 -0
  112. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/datasets/__init__.py +0 -0
  113. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/datasets/_metadata.py +0 -0
  114. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/datasets/_nestorowa.py +0 -0
  115. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/datasets/_pbmc3k.py +0 -0
  116. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/plotting/__init__.py +0 -0
  117. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/plotting/_colors.py +0 -0
  118. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/plotting/_figure.py +0 -0
  119. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/plotting/_typing.py +0 -0
  120. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/preprocessing/__init__.py +0 -0
  121. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/preprocessing/_classification.py +0 -0
  122. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/preprocessing/_duplicates.py +0 -0
  123. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/preprocessing/_filter.py +0 -0
  124. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/preprocessing/_genename.py +0 -0
  125. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/preprocessing/_simple.py +0 -0
  126. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/preprocessing/_transfer.py +0 -0
  127. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/tools/__init__.py +0 -0
  128. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/tools/_binarize.py +0 -0
  129. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/tools/_classification.py +0 -0
  130. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/tools/_clustering.py +0 -0
  131. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/tools/_conversion.py +0 -0
  132. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/tools/_embedding.py +0 -0
  133. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/tools/_graph.py +0 -0
  134. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/tools/_markers.py +0 -0
  135. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/tools/_maths.py +0 -0
  136. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/tools/_regress.py +0 -0
  137. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/tools/_utils.py +0 -0
  138. {bonesistools-1.2.8 → bonesistools-1.3.0}/src/bonesistools/sctools/tools/_write.py +0 -0
  139. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/.placeholder +0 -0
  140. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/__init__.py +0 -0
  141. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/golden/LICENSE.txt +0 -0
  142. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/golden/__init__.py +0 -0
  143. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/golden/expected/hvg_loess.npz +0 -0
  144. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/golden/expected/neighbors.npz +0 -0
  145. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/golden/expected/pca.npz +0 -0
  146. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/golden/expected/qc.npz +0 -0
  147. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/golden/generate_expected.py +0 -0
  148. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/golden/pbmc3k.h5ad +0 -0
  149. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/golden/test_pbmc3k.py +0 -0
  150. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/__init__.py +0 -0
  151. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/bpy/conftest.py +0 -0
  152. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/bpy/test_aggregated_influence_graph.py +0 -0
  153. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/bpy/test_boolean_network.py +0 -0
  154. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/bpy/test_boolean_network_ensemble.py +0 -0
  155. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/bpy/test_hypercube.py +0 -0
  156. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/bpy/test_hypercube_collection.py +0 -0
  157. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/bpy/test_influence_graph.py +0 -0
  158. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/bpy/test_influence_graph_distances.py +0 -0
  159. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/bpy/test_influence_graph_parser.py +0 -0
  160. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/bpy/test_influence_graph_scoring.py +0 -0
  161. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/bpy/test_partial_boolean.py +0 -0
  162. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/bpy/test_plotting_styles.py +0 -0
  163. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/dbs/test_hcop.py +0 -0
  164. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/dbs/test_ncbi.py +0 -0
  165. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/dbs/test_omnipath.py +0 -0
  166. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/sct/__init__.py +0 -0
  167. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/sct/conftest.py +0 -0
  168. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/sct/plotting/test_barplot.py +0 -0
  169. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/sct/plotting/test_colors.py +0 -0
  170. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/sct/plotting/test_density.py +0 -0
  171. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/sct/plotting/test_distribution.py +0 -0
  172. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/sct/plotting/test_figure.py +0 -0
  173. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/sct/plotting/test_graph.py +0 -0
  174. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/sct/plotting/test_scatterplot.py +0 -0
  175. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/sct/preprocessing/test_classification.py +0 -0
  176. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/sct/preprocessing/test_duplicates.py +0 -0
  177. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/sct/preprocessing/test_genename.py +0 -0
  178. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/sct/preprocessing/test_transfer_obs.py +0 -0
  179. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/sct/preprocessing/test_transform.py +0 -0
  180. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/sct/test_typing.py +0 -0
  181. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/sct/tools/test_binarize.py +0 -0
  182. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/sct/tools/test_clustering.py +0 -0
  183. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/sct/tools/test_conversion.py +0 -0
  184. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/sct/tools/test_embedding.py +0 -0
  185. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/sct/tools/test_knnsc.py +0 -0
  186. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/sct/tools/test_markers.py +0 -0
  187. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/sct/tools/test_maths.py +0 -0
  188. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/sct/tools/test_paga.py +0 -0
  189. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/sct/tools/test_regress.py +0 -0
  190. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/sct/tools/test_stats.py +0 -0
  191. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/sct/tools/test_utils.py +0 -0
  192. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/sct/tools/test_write.py +0 -0
  193. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/sct/toy_data.py +0 -0
  194. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/regression/test_validation.py +0 -0
  195. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/reproducibility/__init__.py +0 -0
  196. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/reproducibility/dorothea_current_mouse_A.sha256 +0 -0
  197. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/reproducibility/dorothea_legacy_mouse.sha256 +0 -0
  198. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/reproducibility/test_reproducibility_omnipath.py +0 -0
  199. {bonesistools-1.2.8 → bonesistools-1.3.0}/tests/reproducibility/test_reproducibility_stats.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bonesistools
3
- Version: 1.2.8
3
+ Version: 1.3.0
4
4
  Summary: Bioinformatics toolkit for upstream and downstream analyses around the BoNesis framework
5
5
  Project-URL: Repository, https://github.com/bnediction/bonesistools
6
6
  Author: Théo Roncalli
@@ -5,7 +5,7 @@ build-backend = "hatchling.build"
5
5
  [project]
6
6
  name = "bonesistools"
7
7
  description = "Bioinformatics toolkit for upstream and downstream analyses around the BoNesis framework"
8
- version = "1.2.8"
8
+ version = "1.3.0"
9
9
  license = "CECILL-2.1"
10
10
  credits = ["BNeDiction", "PEPR Santé Numérique 2030"]
11
11
  authors = [
@@ -32,6 +32,8 @@ _GEO_FTP_BASE = "https://ftp.ncbi.nlm.nih.gov/geo"
32
32
  _GSM_PATTERN = re.compile(r"^GSM[0-9]+$")
33
33
  _DOWNLOAD_CHUNK_SIZE = 1024 * 1024
34
34
  _DOWNLOAD_HEADERS = {"User-Agent": "bonesistools"}
35
+ _DOWNLOAD_LABEL_WIDTH = len("barcodes.tsv.gz")
36
+ _DOWNLOAD_SPEED_WIDTH = len("999.99K/s")
35
37
  _SUPPLEMENTARY_SUFFIXES = (
36
38
  "_matrix.mtx.gz",
37
39
  "_barcodes.tsv.gz",
@@ -316,10 +318,12 @@ def _print_download_progress(
316
318
  ) -> None:
317
319
 
318
320
  speed = downloaded / elapsed if elapsed > 0 else 0
321
+ label = _format_download_label(filename)
322
+ speed_label = f"{_format_bytes(speed)}/s"
319
323
  if total is None or total == 0:
320
324
  print(
321
- f"\rdownloading {filename} {_format_bytes(downloaded):>8} "
322
- f"{_format_bytes(speed)}/s",
325
+ f"\r{label} {_format_bytes(downloaded):>8} "
326
+ f"{speed_label:>{_DOWNLOAD_SPEED_WIDTH}}",
323
327
  end="",
324
328
  file=file,
325
329
  flush=True,
@@ -334,8 +338,8 @@ def _print_download_progress(
334
338
  else:
335
339
  bar = "=" * filled + ">" + "." * max(0, width - filled - 1)
336
340
  print(
337
- f"\rdownloading {filename} {percent:3d}%[{bar}] "
338
- f"{_format_bytes(downloaded):>8} {_format_bytes(speed)}/s "
341
+ f"\r{label} {percent:3d}%[{bar}] "
342
+ f"{_format_bytes(downloaded):>8} {speed_label:>{_DOWNLOAD_SPEED_WIDTH}} "
339
343
  f"in {_format_duration(elapsed)}",
340
344
  end="",
341
345
  file=file,
@@ -343,6 +347,11 @@ def _print_download_progress(
343
347
  )
344
348
 
345
349
 
350
+ def _format_download_label(filename: str) -> str:
351
+
352
+ return f"downloading {filename:<{_DOWNLOAD_LABEL_WIDTH}}"
353
+
354
+
346
355
  def _format_bytes(size: float) -> str:
347
356
 
348
357
  units = ("B", "K", "M", "G", "T")
@@ -354,7 +363,7 @@ def _format_bytes(size: float) -> str:
354
363
  return f"{value:.2f}{unit}"
355
364
  value /= 1024
356
365
 
357
- return f"{value:.2f}T"
366
+ return f"{value:.2f}T" # pragma: no cover - defensive fallback
358
367
 
359
368
 
360
369
  def _format_duration(seconds: float) -> str:
@@ -421,7 +430,11 @@ def _read_10x_mtx(
421
430
  feature_path: Path,
422
431
  ) -> AnnData:
423
432
 
424
- counts = sparse.csr_matrix(scipy.io.mmread(str(matrix_path)))
433
+ try:
434
+ matrix = scipy.io.mmread(str(matrix_path), spmatrix=True)
435
+ except TypeError:
436
+ matrix = scipy.io.mmread(str(matrix_path))
437
+ counts = sparse.csr_matrix(matrix)
425
438
  obs_names = pd.Index(
426
439
  _read_table(barcodes_path).iloc[:, 0].astype(str),
427
440
  name=None,
@@ -9,7 +9,7 @@ from __future__ import annotations
9
9
  import os
10
10
  import shutil
11
11
  from pathlib import Path
12
- from typing import Callable, Dict, List
12
+ from typing import Any, Callable, Dict, Iterable, List, Optional
13
13
 
14
14
  import pandas as pd
15
15
  from anndata import AnnData
@@ -25,6 +25,8 @@ _DATASET_LOADERS: Dict[str, _DatasetLoader] = {
25
25
  "nestorowa": _load_nestorowa,
26
26
  "pbmc3k": _load_pbmc3k,
27
27
  }
28
+ _OBSERVATION_COUNT_FIELDS = ("cells", "barcodes", "observations")
29
+ _FEATURE_COUNT_FIELDS = ("genes", "peaks")
28
30
 
29
31
 
30
32
  def load(
@@ -58,11 +60,13 @@ def load(
58
60
  dataset_name = _as_dataset_name(name)
59
61
  quiet = _as_boolean(quiet, "quiet")
60
62
  loader = _DATASET_LOADERS[dataset_name]
61
-
62
- return loader(
63
+ adata = loader(
63
64
  _dataset_cache_dir(dataset_name),
64
65
  quiet,
65
66
  )
67
+ _validate_dataset_shape(dataset_name, adata)
68
+
69
+ return adata
66
70
 
67
71
 
68
72
  def info(name: str) -> Dict[str, object]:
@@ -159,6 +163,84 @@ def _as_dataset_name(name: str) -> str:
159
163
  return dataset_name
160
164
 
161
165
 
166
+ def _validate_dataset_shape(
167
+ name: str,
168
+ adata: AnnData,
169
+ ) -> None:
170
+
171
+ metadata = _DATASETS[name]
172
+ expected_observations = _expected_count(
173
+ metadata,
174
+ _OBSERVATION_COUNT_FIELDS,
175
+ )
176
+ expected_features = _expected_feature_count(metadata)
177
+ errors = []
178
+ if expected_observations is not None and adata.n_obs != expected_observations:
179
+ errors.append(
180
+ f"expected {expected_observations} observations but found "
181
+ f"{adata.n_obs}"
182
+ )
183
+ if expected_features is not None and adata.n_vars != expected_features:
184
+ errors.append(
185
+ f"expected {expected_features} features but found {adata.n_vars}"
186
+ )
187
+ if len(errors) == 0:
188
+ return
189
+
190
+ details = "; ".join(errors)
191
+ raise ValueError(
192
+ f"invalid cached dataset {name!r}: {details}. "
193
+ f"Clear cached files with bt.sct.datasets.clear({name!r}) and retry."
194
+ )
195
+
196
+
197
+ def _expected_count(
198
+ metadata: Dict[str, Any],
199
+ fields: Iterable[str],
200
+ ) -> Optional[int]:
201
+
202
+ for field in fields:
203
+ if field in metadata:
204
+ return _metadata_count(metadata[field], field)
205
+
206
+ return None
207
+
208
+
209
+ def _expected_feature_count(metadata: Dict[str, Any]) -> Optional[int]:
210
+
211
+ if "features" in metadata:
212
+ return _metadata_count(metadata["features"], "features")
213
+
214
+ counts = [
215
+ _metadata_count(metadata[field], field)
216
+ for field in _FEATURE_COUNT_FIELDS
217
+ if field in metadata
218
+ ]
219
+ if len(counts) == 0:
220
+ return None
221
+
222
+ return sum(counts)
223
+
224
+
225
+ def _metadata_count(
226
+ value: object,
227
+ field: str,
228
+ ) -> int:
229
+
230
+ if not isinstance(value, int) or isinstance(value, bool):
231
+ raise TypeError(
232
+ f"invalid dataset metadata for '{field}': expected {int} "
233
+ f"but received {type(value)}"
234
+ )
235
+ if value < 0:
236
+ raise ValueError(
237
+ f"invalid dataset metadata for '{field}': expected non-negative "
238
+ f"value but received {value!r}"
239
+ )
240
+
241
+ return value
242
+
243
+
162
244
  def _dataset_cache_root() -> Path:
163
245
 
164
246
  root = Path(os.environ.get("XDG_CACHE_HOME", Path.home() / ".cache"))
@@ -7,7 +7,7 @@
7
7
  "cells": 1656,
8
8
  "genes": 46078,
9
9
  "source": "NCBI GEO (GSE81682)",
10
- "license": "not specified",
10
+ "license": "Not specified",
11
11
  "url": "https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE81682",
12
12
  "citation": "Nestorowa et al. (2016). A single-cell resolution map of mouse hematopoietic stem and progenitor cell differentiation. Blood, 128(8), e20-e31."
13
13
  },
@@ -30,12 +30,13 @@ from .._typing import ScData, anndata_or_mudata_checker
30
30
  from ._colors import QUALITATIVE_COLORS, generate_colormap
31
31
  from ._utils import (
32
32
  _resolve_legend_argument,
33
+ apply_legend,
33
34
  colormap_colors,
34
35
  colors_from_uns,
35
- figure_from_axes,
36
36
  qualitative_color_values,
37
+ save_figure,
37
38
  set_axis_label,
38
- set_window_title,
39
+ set_title,
39
40
  )
40
41
 
41
42
  Colors = Union[
@@ -48,94 +49,6 @@ Colors = Union[
48
49
  Orientation = Literal["vertical", "horizontal"]
49
50
 
50
51
 
51
- def __ordered_values(
52
- series: pd.Series,
53
- order: Optional[Sequence[object]],
54
- ) -> Sequence[object]:
55
-
56
- if order is not None:
57
- return list(order)
58
-
59
- if isinstance(series.dtype, pd.CategoricalDtype):
60
- return list(series.cat.categories)
61
-
62
- return list(pd.unique(series.dropna()))
63
-
64
-
65
- def __index_from_values(values: Sequence[object], name: str) -> pd.Index:
66
-
67
- return pd.Index(np.asarray(list(values), dtype=object), name=name)
68
-
69
-
70
- def __normalize_colors(
71
- colors: Optional[Colors],
72
- values: Sequence[object],
73
- scdata: ScData,
74
- uns_key: str,
75
- ) -> Sequence[object]:
76
-
77
- if colors is None:
78
- colors = colors_from_uns(scdata, uns_key, values)
79
-
80
- if colors is None:
81
- colors = qualitative_color_values(
82
- len(values),
83
- QUALITATIVE_COLORS,
84
- generate_colormap,
85
- )
86
-
87
- if isinstance(colors, ListedColormap):
88
- colors = colormap_colors(colors)
89
-
90
- if isinstance(colors, str):
91
- colors = plt.get_cmap(colors)
92
-
93
- if isinstance(colors, Colormap):
94
- positions = np.linspace(0, 1, len(values))
95
- return cast(Sequence[object], colors(positions))
96
-
97
- if isinstance(colors, MappingABC):
98
- missing = [value for value in values if value not in colors]
99
-
100
- if missing:
101
- raise KeyError(f"missing colors for values: {missing!r}")
102
-
103
- return [colors[value] for value in values]
104
-
105
- color_values = list(cast(Sequence[object], colors))
106
-
107
- if len(color_values) < len(values):
108
- raise ValueError(
109
- f"invalid argument value for 'colors': "
110
- f"expected at least {len(values)} colors but received {len(color_values)}"
111
- )
112
-
113
- return color_values[0 : len(values)]
114
-
115
-
116
- def __apply_ticklabel_colors(
117
- ax: Axes,
118
- colors: Optional[Mapping[object, object]],
119
- orientation: Orientation,
120
- ) -> None:
121
-
122
- if colors is None:
123
- return None
124
-
125
- ticklabels = (
126
- ax.get_xticklabels() if orientation == "vertical" else ax.get_yticklabels()
127
- )
128
-
129
- for ticklabel in ticklabels:
130
- value = ticklabel.get_text()
131
-
132
- if value in colors:
133
- ticklabel.set_color(cast(Any, colors[value]))
134
- ticklabel.set_fontweight("bold")
135
-
136
- return None
137
-
138
-
139
52
  @overload
140
53
  def composition(
141
54
  scdata: ScData,
@@ -317,12 +230,66 @@ def composition(
317
230
 
318
231
  legend = _resolve_legend_argument(legend, kwargs)
319
232
 
233
+ table, groups, segments = __composition_table(
234
+ scdata,
235
+ obs=obs,
236
+ groupby=groupby,
237
+ obs_order=obs_order,
238
+ group_order=group_order,
239
+ dropna=dropna,
240
+ normalize=normalize,
241
+ )
242
+ color_values = __normalize_colors(colors, segments, scdata, obs)
243
+ fig, ax = __composition_figure(ax, kwargs)
244
+
245
+ bar_kwargs = kwargs["bar"] if "bar" in kwargs else {}
246
+ table.plot(
247
+ kind="bar" if orientation == "vertical" else "barh",
248
+ stacked=True,
249
+ width=width,
250
+ color=color_values,
251
+ ax=ax,
252
+ **bar_kwargs,
253
+ )
254
+
255
+ __set_composition_axes(
256
+ ax,
257
+ normalize=normalize,
258
+ percent=percent,
259
+ orientation=orientation,
260
+ xlabel=xlabel,
261
+ ylabel=ylabel,
262
+ kwargs=kwargs,
263
+ )
264
+
265
+ if group_colors is None:
266
+ group_colors = colors_from_uns(scdata, groupby, groups)
267
+ __apply_ticklabel_colors(ax, group_colors, orientation)
268
+ set_title(fig, ax, title)
269
+ apply_legend(ax, legend, remove=True)
270
+
271
+ if save_figure(fig, outfile):
272
+ return None
273
+
274
+ return fig, ax
275
+
276
+
277
+ def __composition_table(
278
+ scdata: ScData,
279
+ *,
280
+ obs: str,
281
+ groupby: str,
282
+ obs_order: Optional[Sequence[object]],
283
+ group_order: Optional[Sequence[object]],
284
+ dropna: bool,
285
+ normalize: bool,
286
+ ) -> Tuple[pd.DataFrame, Sequence[object], Sequence[object]]:
287
+
320
288
  data = scdata.obs[[groupby, obs]]
321
289
  data = data.dropna() if dropna else data
322
290
 
323
291
  groups = __ordered_values(scdata.obs[groupby], group_order)
324
292
  segments = __ordered_values(scdata.obs[obs], obs_order)
325
-
326
293
  counts = pd.crosstab(data[groupby], data[obs])
327
294
  counts = counts.reindex(
328
295
  index=__index_from_values(groups, groupby),
@@ -330,38 +297,43 @@ def composition(
330
297
  fill_value=0,
331
298
  )
332
299
 
333
- if normalize:
334
- totals = counts.sum(axis=1)
335
- empty_groups = list(totals[totals == 0].index)
300
+ if not normalize:
301
+ return counts, groups, segments
336
302
 
337
- if empty_groups:
338
- raise ValueError(
339
- f"cannot normalize composition for empty groups: {empty_groups!r}"
340
- )
303
+ totals = counts.sum(axis=1)
304
+ empty_groups = list(totals[totals == 0].index)
305
+ if empty_groups:
306
+ raise ValueError(
307
+ f"cannot normalize composition for empty groups: {empty_groups!r}"
308
+ )
309
+ return counts.div(totals, axis=0), groups, segments
341
310
 
342
- table = counts.div(totals, axis=0)
343
- else:
344
- table = counts
345
311
 
346
- color_values = __normalize_colors(colors, segments, scdata, obs)
312
+ def __composition_figure(
313
+ ax: Optional[Axes],
314
+ kwargs: Mapping[str, Any],
315
+ ) -> Tuple[Figure, Axes]:
347
316
 
348
- if ax is None:
349
- fig = plt.figure()
350
- ax = fig.subplots()
351
- fig.set_figheight(kwargs["figheight"] if "figheight" in kwargs else 3)
352
- fig.set_figwidth(kwargs["figwidth"] if "figwidth" in kwargs else 6)
353
- else:
354
- fig = figure_from_axes(ax)
317
+ if ax is not None:
318
+ return cast(Figure, ax.figure), ax
355
319
 
356
- bar_kwargs = kwargs["bar"] if "bar" in kwargs else {}
357
- table.plot(
358
- kind="bar" if orientation == "vertical" else "barh",
359
- stacked=True,
360
- width=width,
361
- color=color_values,
362
- ax=ax,
363
- **bar_kwargs,
364
- )
320
+ fig = plt.figure()
321
+ ax = fig.subplots()
322
+ fig.set_figheight(kwargs["figheight"] if "figheight" in kwargs else 3)
323
+ fig.set_figwidth(kwargs["figwidth"] if "figwidth" in kwargs else 6)
324
+ return fig, ax
325
+
326
+
327
+ def __set_composition_axes(
328
+ ax: Axes,
329
+ *,
330
+ normalize: bool,
331
+ percent: bool,
332
+ orientation: Orientation,
333
+ xlabel: Optional[Union[str, Mapping[str, Any]]],
334
+ ylabel: Optional[Union[str, Mapping[str, Any]]],
335
+ kwargs: Mapping[str, Any],
336
+ ) -> None:
365
337
 
366
338
  set_axis_label(ax, "xlabel", xlabel)
367
339
  set_axis_label(ax, "ylabel", ylabel)
@@ -396,36 +368,92 @@ def composition(
396
368
  )
397
369
  for ticklabel in ticklabels:
398
370
  ticklabel.set_rotation(rotation)
371
+ return None
399
372
 
400
- if group_colors is None:
401
- group_colors = colors_from_uns(scdata, groupby, groups)
402
- __apply_ticklabel_colors(ax, group_colors, orientation)
403
373
 
404
- if title:
405
- if isinstance(title, str):
406
- set_window_title(fig, title)
407
- ax.set_title(title)
408
- elif isinstance(title, dict):
409
- set_window_title(fig, title["label"])
410
- ax.set_title(**title)
411
- else:
412
- raise TypeError(
413
- f"unsupported argument type for 'title': "
414
- f"expected {str} or {dict} but received {type(title)}"
415
- )
416
-
417
- existing_legend = ax.get_legend()
418
-
419
- if legend is True:
420
- ax.legend()
421
- elif legend is not False:
422
- ax.legend(**legend)
423
- elif existing_legend is not None:
424
- existing_legend.remove()
425
-
426
- if outfile:
427
- plt.savefig(outfile, bbox_inches="tight")
428
- plt.close(fig)
374
+ def __ordered_values(
375
+ series: pd.Series,
376
+ order: Optional[Sequence[object]],
377
+ ) -> Sequence[object]:
378
+
379
+ if order is not None:
380
+ return list(order)
381
+
382
+ if isinstance(series.dtype, pd.CategoricalDtype):
383
+ return list(series.cat.categories)
384
+
385
+ return list(pd.unique(series.dropna()))
386
+
387
+
388
+ def __index_from_values(values: Sequence[object], name: str) -> pd.Index:
389
+
390
+ return pd.Index(np.asarray(list(values), dtype=object), name=name)
391
+
392
+
393
+ def __normalize_colors(
394
+ colors: Optional[Colors],
395
+ values: Sequence[object],
396
+ scdata: ScData,
397
+ uns_key: str,
398
+ ) -> Sequence[object]:
399
+
400
+ if colors is None:
401
+ colors = colors_from_uns(scdata, uns_key, values)
402
+
403
+ if colors is None:
404
+ colors = qualitative_color_values(
405
+ len(values),
406
+ QUALITATIVE_COLORS,
407
+ generate_colormap,
408
+ )
409
+
410
+ if isinstance(colors, ListedColormap):
411
+ colors = colormap_colors(colors)
412
+
413
+ if isinstance(colors, str):
414
+ colors = plt.get_cmap(colors)
415
+
416
+ if isinstance(colors, Colormap):
417
+ positions = np.linspace(0, 1, len(values))
418
+ return cast(Sequence[object], colors(positions))
419
+
420
+ if isinstance(colors, MappingABC):
421
+ missing = [value for value in values if value not in colors]
422
+
423
+ if missing:
424
+ raise KeyError(f"missing colors for values: {missing!r}")
425
+
426
+ return [colors[value] for value in values]
427
+
428
+ color_values = list(cast(Sequence[object], colors))
429
+
430
+ if len(color_values) < len(values):
431
+ raise ValueError(
432
+ f"invalid argument value for 'colors': "
433
+ f"expected at least {len(values)} colors but received {len(color_values)}"
434
+ )
435
+
436
+ return color_values[0 : len(values)]
437
+
438
+
439
+ def __apply_ticklabel_colors(
440
+ ax: Axes,
441
+ colors: Optional[Mapping[object, object]],
442
+ orientation: Orientation,
443
+ ) -> None:
444
+
445
+ if colors is None:
429
446
  return None
430
447
 
431
- return fig, ax
448
+ ticklabels = (
449
+ ax.get_xticklabels() if orientation == "vertical" else ax.get_yticklabels()
450
+ )
451
+
452
+ for ticklabel in ticklabels:
453
+ value = ticklabel.get_text()
454
+
455
+ if value in colors:
456
+ ticklabel.set_color(cast(Any, colors[value]))
457
+ ticklabel.set_fontweight("bold")
458
+
459
+ return None