decoupler 2.0.1__tar.gz → 2.0.2__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 (185) hide show
  1. {decoupler-2.0.1 → decoupler-2.0.2}/.github/workflows/test.yaml +1 -0
  2. {decoupler-2.0.1 → decoupler-2.0.2}/LICENSE +1 -1
  3. {decoupler-2.0.1 → decoupler-2.0.2}/PKG-INFO +4 -3
  4. {decoupler-2.0.1 → decoupler-2.0.2}/README.md +1 -1
  5. {decoupler-2.0.1 → decoupler-2.0.2}/pyproject.toml +2 -1
  6. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/bm/metric/_auc.py +9 -10
  7. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/bm/metric/_hmean.py +6 -1
  8. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/mt/_mdt.py +4 -1
  9. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/mt/_udt.py +4 -1
  10. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/pl/_order.py +4 -4
  11. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/pl/_order_targets.py +6 -4
  12. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/pp/anndata.py +6 -4
  13. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/tl/_rankby_order.py +5 -1
  14. decoupler-2.0.2/tests/bm/test_benchmark.py +59 -0
  15. decoupler-2.0.2/tests/bm/test_pl.py +89 -0
  16. {decoupler-2.0.1 → decoupler-2.0.2}/tests/conftest.py +1 -0
  17. {decoupler-2.0.1 → decoupler-2.0.2}/tests/pp/test_anndata.py +0 -1
  18. decoupler-2.0.1/tests/bm/test_benchmark.py +0 -46
  19. {decoupler-2.0.1 → decoupler-2.0.2}/.codecov.yaml +0 -0
  20. {decoupler-2.0.1 → decoupler-2.0.2}/.cruft.json +0 -0
  21. {decoupler-2.0.1 → decoupler-2.0.2}/.editorconfig +0 -0
  22. {decoupler-2.0.1 → decoupler-2.0.2}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  23. {decoupler-2.0.1 → decoupler-2.0.2}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  24. {decoupler-2.0.1 → decoupler-2.0.2}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  25. {decoupler-2.0.1 → decoupler-2.0.2}/.github/workflows/build.yaml +0 -0
  26. {decoupler-2.0.1 → decoupler-2.0.2}/.github/workflows/release.yaml +0 -0
  27. {decoupler-2.0.1 → decoupler-2.0.2}/.gitignore +0 -0
  28. {decoupler-2.0.1 → decoupler-2.0.2}/.pre-commit-config.yaml +0 -0
  29. {decoupler-2.0.1 → decoupler-2.0.2}/.readthedocs.yaml +0 -0
  30. {decoupler-2.0.1 → decoupler-2.0.2}/.vscode/extensions.json +0 -0
  31. {decoupler-2.0.1 → decoupler-2.0.2}/.vscode/launch.json +0 -0
  32. {decoupler-2.0.1 → decoupler-2.0.2}/.vscode/settings.json +0 -0
  33. {decoupler-2.0.1 → decoupler-2.0.2}/CHANGELOG.md +0 -0
  34. {decoupler-2.0.1 → decoupler-2.0.2}/biome.jsonc +0 -0
  35. {decoupler-2.0.1 → decoupler-2.0.2}/docs/_static/.gitkeep +0 -0
  36. {decoupler-2.0.1 → decoupler-2.0.2}/docs/_static/css/custom.css +0 -0
  37. {decoupler-2.0.1 → decoupler-2.0.2}/docs/_static/images/logo.png +0 -0
  38. {decoupler-2.0.1 → decoupler-2.0.2}/docs/_static/images/mlm.png +0 -0
  39. {decoupler-2.0.1 → decoupler-2.0.2}/docs/_static/images/ora.png +0 -0
  40. {decoupler-2.0.1 → decoupler-2.0.2}/docs/_static/images/ulm.png +0 -0
  41. {decoupler-2.0.1 → decoupler-2.0.2}/docs/_templates/.gitkeep +0 -0
  42. {decoupler-2.0.1 → decoupler-2.0.2}/docs/_templates/autosummary/class.rst +0 -0
  43. {decoupler-2.0.1 → decoupler-2.0.2}/docs/api/bm.md +0 -0
  44. {decoupler-2.0.1 → decoupler-2.0.2}/docs/api/ds.md +0 -0
  45. {decoupler-2.0.1 → decoupler-2.0.2}/docs/api/index.md +0 -0
  46. {decoupler-2.0.1 → decoupler-2.0.2}/docs/api/mt.md +0 -0
  47. {decoupler-2.0.1 → decoupler-2.0.2}/docs/api/op.md +0 -0
  48. {decoupler-2.0.1 → decoupler-2.0.2}/docs/api/pl.md +0 -0
  49. {decoupler-2.0.1 → decoupler-2.0.2}/docs/api/pp.md +0 -0
  50. {decoupler-2.0.1 → decoupler-2.0.2}/docs/api/tl.md +0 -0
  51. {decoupler-2.0.1 → decoupler-2.0.2}/docs/changelog.md +0 -0
  52. {decoupler-2.0.1 → decoupler-2.0.2}/docs/conf.py +0 -0
  53. {decoupler-2.0.1 → decoupler-2.0.2}/docs/extensions/typed_returns.py +0 -0
  54. {decoupler-2.0.1 → decoupler-2.0.2}/docs/index.md +0 -0
  55. {decoupler-2.0.1 → decoupler-2.0.2}/docs/notebooks/bench/index.md +0 -0
  56. {decoupler-2.0.1 → decoupler-2.0.2}/docs/notebooks/bench/rna.ipynb +0 -0
  57. {decoupler-2.0.1 → decoupler-2.0.2}/docs/notebooks/bulk/index.md +0 -0
  58. {decoupler-2.0.1 → decoupler-2.0.2}/docs/notebooks/bulk/rna.ipynb +0 -0
  59. {decoupler-2.0.1 → decoupler-2.0.2}/docs/notebooks/example.ipynb +0 -0
  60. {decoupler-2.0.1 → decoupler-2.0.2}/docs/notebooks/index.md +0 -0
  61. {decoupler-2.0.1 → decoupler-2.0.2}/docs/notebooks/omnipath/index.md +0 -0
  62. {decoupler-2.0.1 → decoupler-2.0.2}/docs/notebooks/omnipath/licenses.ipynb +0 -0
  63. {decoupler-2.0.1 → decoupler-2.0.2}/docs/notebooks/omnipath/orthologs.ipynb +0 -0
  64. {decoupler-2.0.1 → decoupler-2.0.2}/docs/notebooks/scell/index.md +0 -0
  65. {decoupler-2.0.1 → decoupler-2.0.2}/docs/notebooks/scell/rna_psbk.ipynb +0 -0
  66. {decoupler-2.0.1 → decoupler-2.0.2}/docs/notebooks/scell/rna_pstime.ipynb +0 -0
  67. {decoupler-2.0.1 → decoupler-2.0.2}/docs/notebooks/scell/rna_sc.ipynb +0 -0
  68. {decoupler-2.0.1 → decoupler-2.0.2}/docs/notebooks/spatial/index.md +0 -0
  69. {decoupler-2.0.1 → decoupler-2.0.2}/docs/notebooks/spatial/rna_visium.ipynb +0 -0
  70. {decoupler-2.0.1 → decoupler-2.0.2}/docs/references.bib +0 -0
  71. {decoupler-2.0.1 → decoupler-2.0.2}/docs/references.md +0 -0
  72. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/_Method.py +0 -0
  73. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/_Plotter.py +0 -0
  74. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/__init__.py +0 -0
  75. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/_datatype.py +0 -0
  76. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/_docs.py +0 -0
  77. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/_download.py +0 -0
  78. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/_log.py +0 -0
  79. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/bm/__init__.py +0 -0
  80. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/bm/_pp.py +0 -0
  81. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/bm/_run.py +0 -0
  82. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/bm/metric/__init__.py +0 -0
  83. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/bm/metric/_fscore.py +0 -0
  84. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/bm/metric/_qrank.py +0 -0
  85. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/bm/pl/__init__.py +0 -0
  86. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/bm/pl/_auc.py +0 -0
  87. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/bm/pl/_bar.py +0 -0
  88. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/bm/pl/_format.py +0 -0
  89. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/bm/pl/_fscore.py +0 -0
  90. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/bm/pl/_qrank.py +0 -0
  91. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/bm/pl/_summary.py +0 -0
  92. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/ds/__init__.py +0 -0
  93. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/ds/_bulk.py +0 -0
  94. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/ds/_scell.py +0 -0
  95. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/ds/_spatial.py +0 -0
  96. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/ds/_toy.py +0 -0
  97. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/ds/_utils.py +0 -0
  98. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/mt/__init__.py +0 -0
  99. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/mt/_aucell.py +0 -0
  100. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/mt/_consensus.py +0 -0
  101. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/mt/_decouple.py +0 -0
  102. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/mt/_gsea.py +0 -0
  103. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/mt/_gsva.py +0 -0
  104. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/mt/_methods.py +0 -0
  105. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/mt/_mlm.py +0 -0
  106. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/mt/_ora.py +0 -0
  107. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/mt/_run.py +0 -0
  108. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/mt/_ulm.py +0 -0
  109. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/mt/_viper.py +0 -0
  110. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/mt/_waggr.py +0 -0
  111. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/mt/_zscore.py +0 -0
  112. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/op/__init__.py +0 -0
  113. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/op/_collectri.py +0 -0
  114. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/op/_dorothea.py +0 -0
  115. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/op/_dtype.py +0 -0
  116. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/op/_hallmark.py +0 -0
  117. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/op/_progeny.py +0 -0
  118. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/op/_resource.py +0 -0
  119. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/op/_translate.py +0 -0
  120. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/pl/__init__.py +0 -0
  121. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/pl/_barplot.py +0 -0
  122. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/pl/_dotplot.py +0 -0
  123. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/pl/_filter_by_expr.py +0 -0
  124. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/pl/_filter_by_prop.py +0 -0
  125. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/pl/_filter_samples.py +0 -0
  126. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/pl/_leading_edge.py +0 -0
  127. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/pl/_network.py +0 -0
  128. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/pl/_obsbar.py +0 -0
  129. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/pl/_obsm.py +0 -0
  130. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/pl/_source_targets.py +0 -0
  131. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/pl/_volcano.py +0 -0
  132. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/pp/__init__.py +0 -0
  133. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/pp/data.py +0 -0
  134. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/pp/net.py +0 -0
  135. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/tl/__init__.py +0 -0
  136. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/tl/_rankby_group.py +0 -0
  137. {decoupler-2.0.1 → decoupler-2.0.2}/src/decoupler/tl/_rankby_obsm.py +0 -0
  138. {decoupler-2.0.1 → decoupler-2.0.2}/tests/ds/test_bulk.py +0 -0
  139. {decoupler-2.0.1 → decoupler-2.0.2}/tests/ds/test_scell.py +0 -0
  140. {decoupler-2.0.1 → decoupler-2.0.2}/tests/ds/test_spatial.py +0 -0
  141. {decoupler-2.0.1 → decoupler-2.0.2}/tests/ds/test_toy.py +0 -0
  142. {decoupler-2.0.1 → decoupler-2.0.2}/tests/ds/test_utils.py +0 -0
  143. {decoupler-2.0.1 → decoupler-2.0.2}/tests/mt/test_aucell.py +0 -0
  144. {decoupler-2.0.1 → decoupler-2.0.2}/tests/mt/test_consensus.py +0 -0
  145. {decoupler-2.0.1 → decoupler-2.0.2}/tests/mt/test_decouple.py +0 -0
  146. {decoupler-2.0.1 → decoupler-2.0.2}/tests/mt/test_gsea.py +0 -0
  147. {decoupler-2.0.1 → decoupler-2.0.2}/tests/mt/test_gsva.py +0 -0
  148. {decoupler-2.0.1 → decoupler-2.0.2}/tests/mt/test_mdt.py +0 -0
  149. {decoupler-2.0.1 → decoupler-2.0.2}/tests/mt/test_methods.py +0 -0
  150. {decoupler-2.0.1 → decoupler-2.0.2}/tests/mt/test_mlm.py +0 -0
  151. {decoupler-2.0.1 → decoupler-2.0.2}/tests/mt/test_ora.py +0 -0
  152. {decoupler-2.0.1 → decoupler-2.0.2}/tests/mt/test_run.py +0 -0
  153. {decoupler-2.0.1 → decoupler-2.0.2}/tests/mt/test_udt.py +0 -0
  154. {decoupler-2.0.1 → decoupler-2.0.2}/tests/mt/test_ulm.py +0 -0
  155. {decoupler-2.0.1 → decoupler-2.0.2}/tests/mt/test_viper.py +0 -0
  156. {decoupler-2.0.1 → decoupler-2.0.2}/tests/mt/test_waggr.py +0 -0
  157. {decoupler-2.0.1 → decoupler-2.0.2}/tests/mt/test_zscore.py +0 -0
  158. {decoupler-2.0.1 → decoupler-2.0.2}/tests/op/test_collectri.py +0 -0
  159. {decoupler-2.0.1 → decoupler-2.0.2}/tests/op/test_dorothea.py +0 -0
  160. {decoupler-2.0.1 → decoupler-2.0.2}/tests/op/test_dtype.py +0 -0
  161. {decoupler-2.0.1 → decoupler-2.0.2}/tests/op/test_hallmark.py +0 -0
  162. {decoupler-2.0.1 → decoupler-2.0.2}/tests/op/test_progeny.py +0 -0
  163. {decoupler-2.0.1 → decoupler-2.0.2}/tests/op/test_resource.py +0 -0
  164. {decoupler-2.0.1 → decoupler-2.0.2}/tests/op/test_translate.py +0 -0
  165. {decoupler-2.0.1 → decoupler-2.0.2}/tests/pl/test_Plotter.py +0 -0
  166. {decoupler-2.0.1 → decoupler-2.0.2}/tests/pl/test_barplot.py +0 -0
  167. {decoupler-2.0.1 → decoupler-2.0.2}/tests/pl/test_dotplot.py +0 -0
  168. {decoupler-2.0.1 → decoupler-2.0.2}/tests/pl/test_filter_by_expr.py +0 -0
  169. {decoupler-2.0.1 → decoupler-2.0.2}/tests/pl/test_filter_by_prop.py +0 -0
  170. {decoupler-2.0.1 → decoupler-2.0.2}/tests/pl/test_filter_samples.py +0 -0
  171. {decoupler-2.0.1 → decoupler-2.0.2}/tests/pl/test_leading_edge.py +0 -0
  172. {decoupler-2.0.1 → decoupler-2.0.2}/tests/pl/test_network.py +0 -0
  173. {decoupler-2.0.1 → decoupler-2.0.2}/tests/pl/test_obsbar.py +0 -0
  174. {decoupler-2.0.1 → decoupler-2.0.2}/tests/pl/test_obsm.py +0 -0
  175. {decoupler-2.0.1 → decoupler-2.0.2}/tests/pl/test_order.py +0 -0
  176. {decoupler-2.0.1 → decoupler-2.0.2}/tests/pl/test_order_targets.py +0 -0
  177. {decoupler-2.0.1 → decoupler-2.0.2}/tests/pl/test_source_targets.py +0 -0
  178. {decoupler-2.0.1 → decoupler-2.0.2}/tests/pl/test_volcano.py +0 -0
  179. {decoupler-2.0.1 → decoupler-2.0.2}/tests/pp/test_data.py +0 -0
  180. {decoupler-2.0.1 → decoupler-2.0.2}/tests/pp/test_net.py +0 -0
  181. {decoupler-2.0.1 → decoupler-2.0.2}/tests/test_download.py +0 -0
  182. {decoupler-2.0.1 → decoupler-2.0.2}/tests/test_version.py +0 -0
  183. {decoupler-2.0.1 → decoupler-2.0.2}/tests/tl/test_rankby_group.py +0 -0
  184. {decoupler-2.0.1 → decoupler-2.0.2}/tests/tl/test_rankby_obsm.py +0 -0
  185. {decoupler-2.0.1 → decoupler-2.0.2}/tests/tl/test_rankby_order.py +0 -0
@@ -78,6 +78,7 @@ jobs:
78
78
  MPLBACKEND: agg
79
79
  PLATFORM: ${{ matrix.os }}
80
80
  DISPLAY: :42
81
+ NUMBA_JIT_COVERAGE: "1"
81
82
  run: uvx hatch run ${{ matrix.env.name }}:run-cov
82
83
  - name: generate coverage report
83
84
  run: uvx hatch run ${{ matrix.env.name }}:coverage xml
@@ -1,6 +1,6 @@
1
1
  BSD 3-Clause License
2
2
 
3
- Copyright (c) 2025, Pau Badia i Mompel
3
+ Copyright (c) 2025, Pau Badia i Mompel, Saez lab
4
4
  All rights reserved.
5
5
 
6
6
  Redistribution and use in source and binary forms, with or without
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: decoupler
3
- Version: 2.0.1
3
+ Version: 2.0.2
4
4
  Summary: Python package to perform enrichment analysis from omics data.
5
5
  Project-URL: Documentation, https://decoupler.readthedocs.io/
6
6
  Project-URL: Homepage, https://github.com/PauBadiaM/decoupler
@@ -9,7 +9,7 @@ Author: Pau Badia i Mompel
9
9
  Maintainer-email: Pau Badia i Mompel <pau.badia@uni-heidelberg.de>
10
10
  License: BSD 3-Clause License
11
11
 
12
- Copyright (c) 2025, Pau Badia i Mompel
12
+ Copyright (c) 2025, Pau Badia i Mompel, Saez lab
13
13
  All rights reserved.
14
14
 
15
15
  Redistribution and use in source and binary forms, with or without
@@ -47,6 +47,7 @@ Requires-Dist: adjusttext
47
47
  Requires-Dist: anndata
48
48
  Requires-Dist: docrep
49
49
  Requires-Dist: igraph
50
+ Requires-Dist: ipywidgets
50
51
  Requires-Dist: marsilea
51
52
  Requires-Dist: numba
52
53
  Requires-Dist: requests
@@ -134,7 +135,7 @@ There are several alternative options to install decoupler:
134
135
  pip install decoupler
135
136
  ```
136
137
 
137
- 2. Install the latest stable version from [conda-forge][conda] using mamba or conda:
138
+ 2. Install the latest stable version from [conda-forge][conda] using mamba or conda (pay attention to the `-py` suffix at the end):
138
139
 
139
140
  ```bash
140
141
  mamba create -n=dcp conda-forge::decoupler-py
@@ -53,7 +53,7 @@ There are several alternative options to install decoupler:
53
53
  pip install decoupler
54
54
  ```
55
55
 
56
- 2. Install the latest stable version from [conda-forge][conda] using mamba or conda:
56
+ 2. Install the latest stable version from [conda-forge][conda] using mamba or conda (pay attention to the `-py` suffix at the end):
57
57
 
58
58
  ```bash
59
59
  mamba create -n=dcp conda-forge::decoupler-py
@@ -4,7 +4,7 @@ requires = [ "hatchling" ]
4
4
 
5
5
  [project]
6
6
  name = "decoupler"
7
- version = "2.0.1"
7
+ version = "2.0.2"
8
8
  description = "Python package to perform enrichment analysis from omics data."
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE" }
@@ -27,6 +27,7 @@ dependencies = [
27
27
  "numba",
28
28
  "docrep",
29
29
  "tqdm",
30
+ "ipywidgets",
30
31
  "xgboost",
31
32
  "seaborn",
32
33
  "requests",
@@ -63,16 +63,13 @@ def auprc(
63
63
  # Compute prc
64
64
  ps = tps + fps
65
65
  msk = ps != 0
66
- if pi0 > 0 and pi0 < 1:
67
- # Siblini W., Fréry J., He-Guelton L., Oblé F., Wang YQ. (2020) Master
68
- # Your Metrics with Calibration. In: Berthold M., Feelders A., Krempl G.
69
- # (eds) Advances in Intelligent Data Analysis XVIII. IDA 2020. Lecture
70
- # Notes in Computer Science, vol 12080. Springer, Cham
71
- pi = np.sum(y_true) / y_true.size
72
- ratio = pi * (1 - pi0) / (pi0 * (1 - pi))
73
- prc = tps[msk] / (tps[msk] + ratio * fps[msk])
74
- else:
75
- prc = np.divide(tps[msk], ps[msk])
66
+ # Siblini W., Fréry J., He-Guelton L., Oblé F., Wang YQ. (2020) Master
67
+ # Your Metrics with Calibration. In: Berthold M., Feelders A., Krempl G.
68
+ # (eds) Advances in Intelligent Data Analysis XVIII. IDA 2020. Lecture
69
+ # Notes in Computer Science, vol 12080. Springer, Cham
70
+ pi = np.sum(y_true) / y_true.size
71
+ ratio = pi * (1 - pi0) / (pi0 * (1 - pi))
72
+ prc = tps[msk] / (tps[msk] + ratio * fps[msk])
76
73
  # Compute rcl
77
74
  rcl = tps / tps[-1]
78
75
  # Flip and add limits
@@ -94,6 +91,8 @@ def auc(
94
91
  """
95
92
  # Normalize to make comparable
96
93
  norm = np.nanmax(np.abs(y_score), axis=1)
94
+ msk = norm == 0.
95
+ norm[msk] = 1.
97
96
  y_score = y_score / norm.reshape(-1, 1)
98
97
  assert ((-1. <= y_score) & (y_score <= 1.)).all()
99
98
  # Flatten and remove nans
@@ -40,6 +40,12 @@ def hmean(
40
40
  -------
41
41
  Dataframe containing the harmonic mean per metric.
42
42
  """
43
+ # Validate
44
+ assert isinstance(df, pd.DataFrame), 'df must be pandas.DataFrame'
45
+ assert isinstance(metrics, (str, list)), 'metrics must be str or list'
46
+ if isinstance(metrics, str):
47
+ metrics = [metrics]
48
+ # Run
43
49
  d_metrics = {
44
50
  'auc': {
45
51
  'name': 'H(auroc, auprc)',
@@ -63,7 +69,6 @@ def hmean(
63
69
  # Compute harmonic mean
64
70
  name = d_metrics[metric]['name']
65
71
  tmp[name] = _hmean(tmp[cols[0]], tmp[cols[1]], beta=beta)
66
- #tmp = tmp.drop(columns=cols)
67
72
  if i == 0:
68
73
  hdf.append(tmp)
69
74
  else:
@@ -1,9 +1,12 @@
1
+ import warnings
1
2
  from typing import Tuple
2
3
 
3
4
  import numpy as np
4
5
  import scipy.sparse as sps
5
6
  from tqdm.auto import tqdm
6
- from xgboost import XGBRegressor
7
+ with warnings.catch_warnings():
8
+ warnings.filterwarnings("ignore", category=FutureWarning, module="xgboost")
9
+ from xgboost import XGBRegressor
7
10
 
8
11
  from decoupler._docs import docs
9
12
  from decoupler._log import _log
@@ -1,9 +1,12 @@
1
+ import warnings
1
2
  from typing import Tuple
2
3
 
3
4
  import numpy as np
4
5
  import scipy.sparse as sps
5
6
  from tqdm.auto import tqdm
6
- from xgboost import XGBRegressor
7
+ with warnings.catch_warnings():
8
+ warnings.filterwarnings("ignore", category=FutureWarning, module="xgboost")
9
+ from xgboost import XGBRegressor
7
10
 
8
11
  from decoupler._docs import docs
9
12
  from decoupler._log import _log
@@ -53,7 +53,7 @@ def order(
53
53
  bp.ax.imshow(
54
54
  colors,
55
55
  aspect='auto',
56
- extent=[0, xmax, 1.05 * ymax, 1.2 * ymax],
56
+ extent=[xmin, xmax, 1.05 * ymax, 1.2 * ymax],
57
57
  transform=bp.ax.transData,
58
58
  zorder=2
59
59
  )
@@ -75,9 +75,9 @@ def order(
75
75
  .groupby(['name', 'order'], as_index=False)['value'].mean()
76
76
  .pivot(index='name', columns='order', values='value')
77
77
  )
78
- img = bp.ax.imshow(mat, extent=[0, xmax, 0, n_names], aspect='auto', **kw_order)
78
+ img = bp.ax.imshow(mat, extent=[xmin, xmax, 0, n_names], aspect='auto', **kw_order)
79
79
  if has_cbar:
80
- bp.ax.imshow(colors, aspect='auto', extent=[0, xmax, n_names, 1.1 * n_names], zorder=2)
80
+ bp.ax.imshow(colors, aspect='auto', extent=[xmin, xmax, n_names, 1.1 * n_names], zorder=2)
81
81
  bp.ax.axhline(y=n_names, c='black', lw=1)
82
82
  bp.ax.set_ylim(0, 1.1 * n_names)
83
83
  bp.fig.colorbar(img, ax=bp.ax, shrink=0.5, label='Mean value', location='top')
@@ -85,5 +85,5 @@ def order(
85
85
  bp.ax.set_yticklabels(np.flip(mat.index))
86
86
  bp.ax.grid(axis='y', visible=False)
87
87
  bp.ax.set_xlabel('order')
88
- bp.ax.set_xlim(0, 1)
88
+ bp.ax.set_xlim(xmin, xmax)
89
89
  return bp._return()
@@ -140,9 +140,11 @@ def order_targets(
140
140
  ax.grid(axis='y', visible=False)
141
141
  ax.set_ylabel('Targets')
142
142
  yticklabels = []
143
+ # Find minmax
144
+ omin, omax = df_ftr['order'].min(), df_ftr['order'].max()
143
145
  # Add neg targets
144
146
  if neg_names.size > 0:
145
- img = ax.imshow(mat.loc[neg_names], extent=[0, 1, 0, neg_names.size], aspect='auto', cmap=neg_cmap, vmin=vmin, vmax=vmax)
147
+ img = ax.imshow(mat.loc[neg_names], extent=[omin, omax, 0, neg_names.size], aspect='auto', cmap=neg_cmap, vmin=vmin, vmax=vmax)
146
148
  yticklabels.extend(list(neg_names)[::-1])
147
149
  cbar_mappable = ScalarMappable(cmap=neg_cmap, norm=Normalize(vmin=vmin, vmax=vmax))
148
150
  pos = ax.get_position().bounds
@@ -152,22 +154,22 @@ def order_targets(
152
154
  ax.axhline(y=neg_names.size, c='black', lw=1)
153
155
  # Add pos targets
154
156
  if pos_names.size > 0:
155
- img = ax.imshow(mat.loc[pos_names], extent=[0, 1, neg_names.size, neg_names.size + pos_names.size], aspect='auto', cmap='Reds', vmin=vmin, vmax=vmax)
157
+ img = ax.imshow(mat.loc[pos_names], extent=[omin, omax, neg_names.size, neg_names.size + pos_names.size], aspect='auto', cmap='Reds', vmin=vmin, vmax=vmax)
156
158
  yticklabels.extend(list(pos_names)[::-1])
157
159
  cbar_mappable = ScalarMappable(cmap=pos_cmap, norm=Normalize(vmin=vmin, vmax=vmax))
158
160
  pos = ax.get_position().bounds
159
- # (left, bottom, width, height)
160
161
  cax = bp.fig.add_axes([0.97, pos[1] + (pos[3] / 2) + .025, 0.05, (pos[3] / 2) - .025])
161
162
  cax.grid(axis='y', visible=False)
162
163
  bp.fig.colorbar(cbar_mappable, cax=cax, aspect=5, shrink=0.5, label='+ target\nvalues', location='right')
163
164
  # Plot labels
164
165
  ax.set_ylim(0, n_names)
165
166
  if has_cbar:
166
- ax.imshow(colors, aspect='auto', extent=[0, 1, n_names, 1.1 * n_names], zorder=2)
167
+ ax.imshow(colors, aspect='auto', extent=[omin, omax, n_names, 1.1 * n_names], zorder=2)
167
168
  ax.axhline(y=n_names, c='black', lw=1)
168
169
  ax.set_ylim(0, 1.1 * n_names)
169
170
  # Format plot
170
171
  ax.set_yticks(np.arange(n_names) + 0.5)
171
172
  ax.set_yticklabels(yticklabels)
173
+ ax.set_xlim(omin, omax)
172
174
  bp.fig.subplots_adjust(hspace=0)
173
175
  return bp._return()
@@ -151,6 +151,10 @@ def _sample_group_by(
151
151
  # Use one column if the same
152
152
  if sample == group:
153
153
  group = None
154
+ # Handle list columns
155
+ ocols = obs.select_dtypes(include='object').columns
156
+ for ocol in ocols:
157
+ obs[ocol] = obs[ocol].str.join('_')
154
158
  if group is None:
155
159
  # Filter extra columns in obs
156
160
  cols = obs.groupby(sample, observed=True).nunique(dropna=False).eq(other=1).all(axis=0)
@@ -703,10 +707,9 @@ def bin_order(
703
707
  if sps.issparse(X):
704
708
  X = X.toarray()
705
709
  y = adata.obs[order].values
706
- # Normalize to 0 and 1
707
- y = np.abs(y) / np.abs(y).max()
708
710
  # Make windows
709
- bin_edges = np.linspace(0, 1, nbins + 1)
711
+ ymin, ymax = y.min(), y.max()
712
+ bin_edges = np.linspace(start=ymin, stop=ymax, num=nbins + 1)
710
713
  bin_midpoints = (bin_edges[:-1] + bin_edges[1:]) / 2
711
714
  # Prepare label colors
712
715
  cols = ['name', 'midpoint', 'value']
@@ -735,5 +738,4 @@ def bin_order(
735
738
  df = pd.concat(dfs)
736
739
  df = df[cols]
737
740
  df = df.rename(columns={'midpoint': 'order'}).reset_index(drop=True)
738
- df['order'] = df['order'] / df['order'].max()
739
741
  return df
@@ -1,8 +1,12 @@
1
+ import warnings
2
+
1
3
  import pandas as pd
2
4
  import scipy.stats as sts
3
5
  import scipy.sparse as sps
6
+ with warnings.catch_warnings():
7
+ warnings.filterwarnings("ignore", category=FutureWarning, module="xgboost")
8
+ from xgboost import XGBRegressor
4
9
  from anndata import AnnData
5
- from xgboost import XGBRegressor
6
10
 
7
11
  from decoupler._docs import docs
8
12
  from decoupler.pp.data import extract
@@ -0,0 +1,59 @@
1
+ import pandas as pd
2
+ import scipy.sparse as sps
3
+ import pytest
4
+
5
+ import decoupler as dc
6
+
7
+
8
+ @pytest.mark.parametrize(
9
+ 'metrics,groupby,runby,sfilt,thr,emin,mnet',
10
+ [
11
+ ['auc', None, 'expr', False, 0.05, 5, False],
12
+ ['auc', None, 'expr', True, 0.05, 5, False],
13
+ [['auc'], None, 'expr', False, 0.05, 5, False],
14
+ [['auc', 'fscore'], 'group', 'expr', False, 0.05, 5, False],
15
+ [['auc', 'fscore', 'qrank'], None, 'source', False, 0.05, 2, False],
16
+ [['auc', 'fscore', 'qrank'], 'group', 'source', False, 0.05, 1, False],
17
+ [['auc', 'fscore', 'qrank'], 'bm_group', 'expr', True, 0.05, 5, False],
18
+ [['auc', 'fscore', 'qrank'], 'source', 'expr', True, 0.05, 5, False],
19
+ ]
20
+ )
21
+ def test_benchmark(
22
+ bdata,
23
+ net,
24
+ metrics,
25
+ groupby,
26
+ runby,
27
+ sfilt,
28
+ thr,
29
+ emin,
30
+ mnet,
31
+ rng,
32
+ ):
33
+ dc.mt.ulm(data=bdata, net=net, tmin=0)
34
+ if mnet:
35
+ net = {'w_net': net, 'unw_net': net.drop(columns=['weight'])}
36
+ bdata = bdata.copy()
37
+ bdata.obs['source'] = rng.choice(['x', 'y', 'z'], size=bdata.n_obs, replace=True)
38
+ bdata.X = sps.csr_matrix(bdata.X)
39
+ df = dc.bm.benchmark(
40
+ adata=bdata,
41
+ net=net,
42
+ metrics=metrics,
43
+ groupby=groupby,
44
+ runby=runby,
45
+ sfilt=sfilt,
46
+ thr=thr,
47
+ emin=emin,
48
+ kws_decouple={
49
+ 'cons': True,
50
+ 'tmin': 3,
51
+ 'methods': ['ulm', 'zscore', 'aucell']
52
+ },
53
+ verbose=True
54
+ )
55
+ assert isinstance(df, pd.DataFrame)
56
+ cols = {'method', 'metric', 'score'}
57
+ assert cols.issubset(df.columns)
58
+ hdf = dc.bm.metric.hmean(df, metrics=metrics)
59
+ assert isinstance(hdf, pd.DataFrame)
@@ -0,0 +1,89 @@
1
+ import pandas as pd
2
+ import matplotlib
3
+ matplotlib.use("Agg")
4
+ import matplotlib.pyplot as plt
5
+ from matplotlib.figure import Figure
6
+ import pytest
7
+
8
+ import decoupler as dc
9
+
10
+ @pytest.fixture
11
+ def df():
12
+ df = pd.DataFrame(
13
+ data=[
14
+ ['aucell', 'auroc', 0.45],
15
+ ['aucell', 'auprc', 0.55],
16
+ ['ulm', 'auroc', 0.9],
17
+ ['ulm', 'auprc', 0.8],
18
+ ['aucell', 'recall', 0.45],
19
+ ['aucell', 'precision', 0.55],
20
+ ['ulm', 'recall', 0.9],
21
+ ['ulm', 'precision', 0.8],
22
+ ['aucell', '1-qrank', 0.45],
23
+ ['aucell', '-log10(pval)', 0.9],
24
+ ['ulm', '1-qrank', 0.9],
25
+ ['ulm', '-log10(pval)', 5.6],
26
+ ],
27
+ columns = ['method', 'metric', 'score']
28
+ )
29
+ return df
30
+
31
+
32
+ @pytest.fixture
33
+ def hdf(
34
+ df,
35
+ ):
36
+ hdf = dc.bm.metric.hmean(df)
37
+ return hdf
38
+
39
+
40
+ def test_auc(
41
+ df,
42
+ ):
43
+ fig = dc.bm.pl.auc(df=df, hue=None, return_fig=True)
44
+ assert isinstance(fig, Figure)
45
+ plt.close(fig)
46
+ fig = dc.bm.pl.auc(df=df, hue='method', return_fig=True)
47
+ assert isinstance(fig, Figure)
48
+ plt.close(fig)
49
+
50
+
51
+ def test_fscore(
52
+ df,
53
+ ):
54
+ fig = dc.bm.pl.fscore(df=df, hue=None, return_fig=True)
55
+ assert isinstance(fig, Figure)
56
+ plt.close(fig)
57
+ fig = dc.bm.pl.fscore(df=df, hue='method', return_fig=True)
58
+ assert isinstance(fig, Figure)
59
+ plt.close(fig)
60
+
61
+
62
+ def test_qrank(
63
+ df,
64
+ ):
65
+ fig = dc.bm.pl.qrank(df=df, hue=None, return_fig=True)
66
+ assert isinstance(fig, Figure)
67
+ plt.close(fig)
68
+ fig = dc.bm.pl.qrank(df=df, hue='method', return_fig=True)
69
+ assert isinstance(fig, Figure)
70
+ plt.close(fig)
71
+
72
+
73
+ def test_bar(
74
+ hdf,
75
+ ):
76
+ fig = dc.bm.pl.bar(df=hdf, x='H(auroc, auprc)', y='method', hue=None, return_fig=True)
77
+ assert isinstance(fig, Figure)
78
+ plt.close(fig)
79
+ fig = dc.bm.pl.bar(df=hdf, x='H(auroc, auprc)', y='method', hue='method', return_fig=True)
80
+ assert isinstance(fig, Figure)
81
+ plt.close(fig)
82
+
83
+
84
+ def test_summary(
85
+ hdf,
86
+ ):
87
+ fig = dc.bm.pl.summary(df=hdf, y='method', figsize=(6, 3), return_fig=True)
88
+ assert isinstance(fig, Figure)
89
+ plt.close(fig)
@@ -49,6 +49,7 @@ def pdata(
49
49
  @pytest.fixture
50
50
  def bdata():
51
51
  adata, _ = dc.ds.toy_bench(nobs=100, nvar=20, bval=2, seed=42, verbose=False)
52
+ adata.obs['bm_group'] = adata.obs.apply(lambda x: [x['sample'], x['group']], axis=1)
52
53
  return adata
53
54
 
54
55
 
@@ -250,7 +250,6 @@ def test_bin_order(
250
250
  cols = {'name', 'order', 'value'}
251
251
  assert cols.issubset(df.columns)
252
252
  assert ((0. <= df['order']) & (df['order'] <= 1.)).all()
253
- assert df['order'].unique().size == np.min([tdata.n_obs, nbins])
254
253
  if label is not None:
255
254
  lcols = {'label', 'color'}
256
255
  assert lcols.issubset(df.columns)
@@ -1,46 +0,0 @@
1
- import pandas as pd
2
- import pytest
3
-
4
- import decoupler as dc
5
-
6
-
7
- @pytest.mark.parametrize(
8
- 'metrics,groupby,runby,sfilt,thr,emin',
9
- [
10
- ['auc', None, 'expr', False, 0.05, 5],
11
- ['auc', None, 'expr', True, 0.05, 5],
12
- [['auc'], None, 'expr', False, 0.05, 5],
13
- [['auc', 'fscore'], 'group', 'expr', False, 0.05, 5],
14
- [['auc', 'fscore', 'qrank'], None, 'source', False, 0.05, 2],
15
- [['auc', 'fscore', 'qrank'], 'group', 'source', False, 0.05, 1],
16
- ]
17
- )
18
- def test_benchmark(
19
- bdata,
20
- net,
21
- metrics,
22
- groupby,
23
- runby,
24
- sfilt,
25
- thr,
26
- emin,
27
- ):
28
- df = dc.bm.benchmark(
29
- adata=bdata,
30
- net=net,
31
- metrics=metrics,
32
- groupby=groupby,
33
- runby=runby,
34
- sfilt=sfilt,
35
- thr=thr,
36
- emin=emin,
37
- kws_decouple={
38
- 'cons': True,
39
- 'tmin': 3,
40
- 'methods': ['ulm', 'zscore']
41
- },
42
- )
43
- assert isinstance(df, pd.DataFrame)
44
- cols = {'method', 'metric', 'score'}
45
- print(df.columns)
46
- assert cols.issubset(df.columns)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes