exprmat 0.2.79__tar.gz → 0.2.81__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 (472) hide show
  1. {exprmat-0.2.79 → exprmat-0.2.81}/PKG-INFO +1 -1
  2. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/__init__.py +3 -0
  3. exprmat-0.2.81/exprmat/data/malig.py +16 -0
  4. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/data/signature.py +4 -1
  5. exprmat-0.2.81/exprmat/malig/__init__.py +45 -0
  6. exprmat-0.2.81/exprmat/malig/classifier.py +439 -0
  7. exprmat-0.2.81/exprmat/malig/scoring.py +156 -0
  8. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/experiment.py +3 -3
  9. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/rna/__init__.py +9 -2
  10. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/rna/interaction.py +1 -1
  11. exprmat-0.2.81/exprmat/reader/rna/malig.py +119 -0
  12. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/rna/markers.py +16 -1
  13. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/rna/repertoire.py +7 -7
  14. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/rna/trajectory.py +5 -1
  15. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reduction/nn.py +2 -0
  16. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/wgcna/__init__.py +3 -3
  17. {exprmat-0.2.79 → exprmat-0.2.81}/pyproject.toml +1 -1
  18. {exprmat-0.2.79 → exprmat-0.2.81}/Cargo.lock +0 -0
  19. {exprmat-0.2.79 → exprmat-0.2.81}/Cargo.toml +0 -0
  20. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/ansi.py +0 -0
  21. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/clustering/__init__.py +0 -0
  22. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/clustering/cnmf.py +0 -0
  23. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/clustering/dbscan.py +0 -0
  24. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/clustering/gating.py +0 -0
  25. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/clustering/kmeans.py +0 -0
  26. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/clustering/leiden.py +0 -0
  27. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/clustering/nmf.py +0 -0
  28. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/clustering/rogue.py +0 -0
  29. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/clustering/sc3.py +0 -0
  30. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/clustering/seriation.py +0 -0
  31. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/clustering/spectral.py +0 -0
  32. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/clustering/utils.py +0 -0
  33. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/cnv/__init__.py +0 -0
  34. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/cnv/cnvscore.py +0 -0
  35. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/cnv/infercnv.py +0 -0
  36. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/configuration.py +0 -0
  37. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/data/__init__.py +0 -0
  38. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/data/cistarget.py +0 -0
  39. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/data/cre.py +0 -0
  40. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/data/decoupler.py +0 -0
  41. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/data/finders.py +0 -0
  42. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/data/geneset.py +0 -0
  43. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/data/icnet.py +0 -0
  44. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/data/io.py +0 -0
  45. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/data/lr.py +0 -0
  46. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/data/orthologs.py +0 -0
  47. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/data/presets.py +0 -0
  48. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/data/repertoire.py +0 -0
  49. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/data/tf.py +0 -0
  50. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/deconv/__init__.py +0 -0
  51. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/deconv/deconv.py +0 -0
  52. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/deconv/simulation.py +0 -0
  53. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/deconv/tangram/__init__.py +0 -0
  54. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/deconv/tangram/mapping.py +0 -0
  55. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/deconv/tangram/optimizer.py +0 -0
  56. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/deconv/tangram/spatial.py +0 -0
  57. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/deconv/tangram/utils.py +0 -0
  58. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/descriptive/__init__.py +0 -0
  59. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/descriptive/aggregate.py +0 -0
  60. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/descriptive/atac.py +0 -0
  61. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/descriptive/aucell.py +0 -0
  62. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/descriptive/composition.py +0 -0
  63. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/descriptive/covar.py +0 -0
  64. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/descriptive/de.py +0 -0
  65. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/descriptive/geneset.py +0 -0
  66. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/descriptive/gse.py +0 -0
  67. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/descriptive/kde.py +0 -0
  68. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/descriptive/recovery.py +0 -0
  69. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/descriptive/sccoda.py +0 -0
  70. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/descriptive/summary.py +0 -0
  71. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/descriptive/tcr.py +0 -0
  72. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/deseq/dataset.py +0 -0
  73. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/deseq/gridsearch.py +0 -0
  74. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/deseq/inference.py +0 -0
  75. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/deseq/preprocessing.py +0 -0
  76. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/deseq/stats.py +0 -0
  77. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/deseq/utils.py +0 -0
  78. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/domain/__init__.py +0 -0
  79. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/domain/deepst/__init__.py +0 -0
  80. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/domain/deepst/adjacency.py +0 -0
  81. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/domain/deepst/api.py +0 -0
  82. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/domain/deepst/augment.py +0 -0
  83. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/domain/deepst/image_features.py +0 -0
  84. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/domain/deepst/model.py +0 -0
  85. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/domain/deepst/runner.py +0 -0
  86. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/domain/deepst/trainer.py +0 -0
  87. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/domain/spagcn/__init__.py +0 -0
  88. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/domain/spagcn/adjacency.py +0 -0
  89. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/domain/spagcn/api.py +0 -0
  90. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/domain/spagcn/layers.py +0 -0
  91. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/domain/spagcn/models.py +0 -0
  92. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/domain/spagcn/morans.py +0 -0
  93. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/domain/spagcn/spagcn.py +0 -0
  94. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/domain/spagcn/svg.py +0 -0
  95. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/domain/spatialde/__init__.py +0 -0
  96. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/domain/spatialde/api.py +0 -0
  97. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/domain/spatialde/kernels.py +0 -0
  98. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/domain/spatialde/score_test.py +0 -0
  99. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/dynamics/__init__.py +0 -0
  100. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/dynamics/generank.py +0 -0
  101. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/dynamics/linreg.py +0 -0
  102. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/dynamics/moments.py +0 -0
  103. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/dynamics/optimization.py +0 -0
  104. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/dynamics/parallel.py +0 -0
  105. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/dynamics/preprocess.py +0 -0
  106. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/dynamics/pseudotime.py +0 -0
  107. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/dynamics/transition.py +0 -0
  108. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/dynamics/utils.py +0 -0
  109. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/dynamics/velocity.py +0 -0
  110. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/grn/__init__.py +0 -0
  111. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/grn/infergrn.py +0 -0
  112. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/grn/modules.py +0 -0
  113. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/grn/prune.py +0 -0
  114. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/grn/regressors.py +0 -0
  115. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/grn/utils.py +0 -0
  116. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/help.py +0 -0
  117. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/image/__init__.py +0 -0
  118. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/image/augment.py +0 -0
  119. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/image/axis.py +0 -0
  120. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/image/channel.py +0 -0
  121. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/image/compensation.py +0 -0
  122. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/image/density.py +0 -0
  123. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/image/segmentation.py +0 -0
  124. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/image/tissue.py +0 -0
  125. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/image/transform.py +0 -0
  126. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/lr/__init__.py +0 -0
  127. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/lr/aggregate.py +0 -0
  128. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/lr/cellnest/__init__.py +0 -0
  129. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/lr/cellnest/api.py +0 -0
  130. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/lr/cellnest/gat.py +0 -0
  131. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/lr/cellnest/intra.py +0 -0
  132. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/lr/cellnest/model.py +0 -0
  133. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/lr/cellnest/plotting.py +0 -0
  134. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/lr/cellnest/postprocess.py +0 -0
  135. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/lr/cellnest/preprocess.py +0 -0
  136. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/lr/cellnest/relay.py +0 -0
  137. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/lr/cellnest/stats.py +0 -0
  138. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/lr/cellnest/train.py +0 -0
  139. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/lr/cellnest/utils.py +0 -0
  140. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/lr/icnet/__init__.py +0 -0
  141. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/lr/icnet/construction.py +0 -0
  142. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/lr/icnet/importance.py +0 -0
  143. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/lr/icnet/ligand.py +0 -0
  144. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/lr/icnet/metrics.py +0 -0
  145. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/lr/icnet/pagerank.py +0 -0
  146. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/lr/method.py +0 -0
  147. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/lr/methods/__init__.py +0 -0
  148. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/lr/methods/cellchat.py +0 -0
  149. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/lr/methods/cellphonedb.py +0 -0
  150. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/lr/methods/connectome.py +0 -0
  151. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/lr/methods/geomean.py +0 -0
  152. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/lr/methods/logfc.py +0 -0
  153. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/lr/methods/natmi.py +0 -0
  154. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/lr/methods/rank_aggregate.py +0 -0
  155. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/lr/methods/scseqcomm.py +0 -0
  156. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/lr/methods/singlecellsignalr.py +0 -0
  157. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/lr/pipeline.py +0 -0
  158. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/lr/preprocess.py +0 -0
  159. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/lr/resources.py +0 -0
  160. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/lr/utils.py +0 -0
  161. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/metacell/__init__.py +0 -0
  162. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/metacell/engine.py +0 -0
  163. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/metacell/model.py +0 -0
  164. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/metacell/utils.py +0 -0
  165. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/nmf/__init__.py +0 -0
  166. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/nmf/methods/factorization/__init__.py +0 -0
  167. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/nmf/methods/factorization/bd.py +0 -0
  168. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/nmf/methods/factorization/bmf.py +0 -0
  169. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/nmf/methods/factorization/icm.py +0 -0
  170. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/nmf/methods/factorization/lfnmf.py +0 -0
  171. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/nmf/methods/factorization/lsnmf.py +0 -0
  172. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/nmf/methods/factorization/nmf.py +0 -0
  173. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/nmf/methods/factorization/nsnmf.py +0 -0
  174. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/nmf/methods/factorization/pmf.py +0 -0
  175. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/nmf/methods/factorization/pmfcc.py +0 -0
  176. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/nmf/methods/factorization/psmf.py +0 -0
  177. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/nmf/methods/factorization/sepnmf.py +0 -0
  178. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/nmf/methods/factorization/snmf.py +0 -0
  179. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/nmf/methods/factorization/snmnmf.py +0 -0
  180. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/nmf/methods/seeding/__init__.py +0 -0
  181. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/nmf/methods/seeding/fixed.py +0 -0
  182. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/nmf/methods/seeding/nndsvd.py +0 -0
  183. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/nmf/methods/seeding/random.py +0 -0
  184. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/nmf/methods/seeding/random_c.py +0 -0
  185. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/nmf/methods/seeding/random_vcol.py +0 -0
  186. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/nmf/models/__init__.py +0 -0
  187. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/nmf/models/mf_fit.py +0 -0
  188. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/nmf/models/mf_track.py +0 -0
  189. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/nmf/models/nmf.py +0 -0
  190. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/nmf/models/nmf_mm.py +0 -0
  191. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/nmf/models/nmf_ns.py +0 -0
  192. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/nmf/models/nmf_std.py +0 -0
  193. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/nmf/models/smf.py +0 -0
  194. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/nmf/utils/__init__.py +0 -0
  195. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/nmf/utils/linalg.py +0 -0
  196. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/nmf/utils/utils.py +0 -0
  197. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/parser/__init__.py +0 -0
  198. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/parser/converter.py +0 -0
  199. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/parser/rds.py +0 -0
  200. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/parser/seurat.py +0 -0
  201. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/peaks/__init__.py +0 -0
  202. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/peaks/callpeak.py +0 -0
  203. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/peaks/common.py +0 -0
  204. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/peaks/coverage.py +0 -0
  205. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/peaks/footprint.py +0 -0
  206. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/peaks/idr/__init__.py +0 -0
  207. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/peaks/idr/constants.py +0 -0
  208. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/peaks/idr/idr.py +0 -0
  209. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/peaks/idr/invcdf.pyx +0 -0
  210. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/peaks/idr/optimization.py +0 -0
  211. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/peaks/idr/utils.py +0 -0
  212. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/peaks/linkage.py +0 -0
  213. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/peaks/motif.py +0 -0
  214. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/peaks/sequence.py +0 -0
  215. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/__init__.py +0 -0
  216. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/atac.py +0 -0
  217. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/cnmf.py +0 -0
  218. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/cnv.py +0 -0
  219. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/data/A.pk +0 -0
  220. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/data/B.pk +0 -0
  221. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/data/C.pk +0 -0
  222. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/data/D.pk +0 -0
  223. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/data/E.pk +0 -0
  224. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/data/F.pk +0 -0
  225. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/data/G.pk +0 -0
  226. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/data/H.pk +0 -0
  227. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/data/I.pk +0 -0
  228. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/data/J.pk +0 -0
  229. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/data/K.pk +0 -0
  230. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/data/L.pk +0 -0
  231. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/data/M.pk +0 -0
  232. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/data/N.pk +0 -0
  233. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/data/O.pk +0 -0
  234. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/data/P.pk +0 -0
  235. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/data/Q.pk +0 -0
  236. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/data/R.pk +0 -0
  237. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/data/S.pk +0 -0
  238. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/data/T.pk +0 -0
  239. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/data/U.pk +0 -0
  240. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/data/V.pk +0 -0
  241. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/data/W.pk +0 -0
  242. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/data/X.pk +0 -0
  243. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/data/Y.pk +0 -0
  244. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/data/Z.pk +0 -0
  245. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/de.py +0 -0
  246. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/expression.py +0 -0
  247. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/gse.py +0 -0
  248. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/icnet.py +0 -0
  249. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/knee.py +0 -0
  250. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/lr.py +0 -0
  251. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/matrix.py +0 -0
  252. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/milestone.py +0 -0
  253. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/network.py +0 -0
  254. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/order.py +0 -0
  255. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/palettes.py +0 -0
  256. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/proximity.py +0 -0
  257. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/sankey.py +0 -0
  258. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/sequence.py +0 -0
  259. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/summary.py +0 -0
  260. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/track.py +0 -0
  261. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/trajectory.py +0 -0
  262. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/utils.py +0 -0
  263. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/velocity.py +0 -0
  264. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/plotting/wgcna.py +0 -0
  265. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/preprocessing/__init__.py +0 -0
  266. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/preprocessing/background/__init__.py +0 -0
  267. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/preprocessing/background/correction.py +0 -0
  268. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/preprocessing/background/dirichlet_multinomial.py +0 -0
  269. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/preprocessing/background/emptydrops.py +0 -0
  270. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/preprocessing/background/estimation.py +0 -0
  271. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/preprocessing/background/multinomial.py +0 -0
  272. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/preprocessing/background/sgt.py +0 -0
  273. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/preprocessing/background/soupx.py +0 -0
  274. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/preprocessing/doublets/__init__.py +0 -0
  275. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/preprocessing/doublets/composite.py +0 -0
  276. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/preprocessing/doublets/ddetect.py +0 -0
  277. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/preprocessing/doublets/scrublet.py +0 -0
  278. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/preprocessing/emptydrops.py +0 -0
  279. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/preprocessing/filter.py +0 -0
  280. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/preprocessing/impute/__init__.py +0 -0
  281. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/preprocessing/impute/magic.py +0 -0
  282. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/preprocessing/integrate.py +0 -0
  283. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/preprocessing/linear.py +0 -0
  284. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/preprocessing/normal.py +0 -0
  285. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/preprocessing/plot.py +0 -0
  286. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/preprocessing/qc.py +0 -0
  287. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/preprocessing/sctransform/__init__.py +0 -0
  288. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/preprocessing/sctransform/estimate.py +0 -0
  289. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/preprocessing/sctransform/ksmooth.py +0 -0
  290. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/preprocessing/sctransform/residual.py +0 -0
  291. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/preprocessing/sctransform/transform.py +0 -0
  292. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/preprocessing/sparse.py +0 -0
  293. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/preprocessing/uniform.py +0 -0
  294. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/__init__.py +0 -0
  295. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/accessor.py +0 -0
  296. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/atac/__init__.py +0 -0
  297. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/atac/derive.py +0 -0
  298. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/atac/peaks.py +0 -0
  299. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/atac/preprocessing.py +0 -0
  300. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/cite/__init__.py +0 -0
  301. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/cite/preprocessing.py +0 -0
  302. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/conversions.py +0 -0
  303. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/data-structure.txt +0 -0
  304. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/general/__init__.py +0 -0
  305. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/history.py +0 -0
  306. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/introspect.py +0 -0
  307. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/introspective.txt +0 -0
  308. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/matcher.py +0 -0
  309. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/metadata.py +0 -0
  310. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/rna/atlas.py +0 -0
  311. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/rna/bulk.py +0 -0
  312. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/rna/cnv.py +0 -0
  313. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/rna/geneset.py +0 -0
  314. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/rna/getter.py +0 -0
  315. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/rna/impute.py +0 -0
  316. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/rna/nmf.py +0 -0
  317. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/rna/proportion.py +0 -0
  318. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/rna/qc.py +0 -0
  319. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/rna/reduction.py +0 -0
  320. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/rna/summarize.py +0 -0
  321. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/schema.py +0 -0
  322. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/spatial/__init__.py +0 -0
  323. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/spatial/classifier.py +0 -0
  324. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/spatial/coordinates.py +0 -0
  325. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/spatial/deconv.py +0 -0
  326. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/spatial/density.py +0 -0
  327. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/spatial/domains.py +0 -0
  328. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/spatial/getter.py +0 -0
  329. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/spatial/graph.py +0 -0
  330. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/spatial/image.py +0 -0
  331. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/spatial/lr.py +0 -0
  332. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/spatial/proximity.py +0 -0
  333. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/spatial/qc.py +0 -0
  334. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/spatial/segmentation.py +0 -0
  335. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/spatial/snn.py +0 -0
  336. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/spatial/tmap.py +0 -0
  337. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/spatial/transform.py +0 -0
  338. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/static.py +0 -0
  339. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reader/updater.py +0 -0
  340. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reduction/__init__.py +0 -0
  341. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reduction/diffmap.py +0 -0
  342. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reduction/forceatlas.py +0 -0
  343. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reduction/mde.py +0 -0
  344. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reduction/outliers.py +0 -0
  345. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reduction/pca.py +0 -0
  346. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reduction/plot.py +0 -0
  347. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reduction/scvi.py +0 -0
  348. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reduction/spectral.py +0 -0
  349. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reduction/tsne.py +0 -0
  350. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reduction/umap.py +0 -0
  351. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reduction/wnn/__init__.py +0 -0
  352. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reduction/wnn/landmarks.py +0 -0
  353. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reduction/wnn/plan.md +0 -0
  354. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reduction/wnn/projection.py +0 -0
  355. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reduction/wnn/refinement.py +0 -0
  356. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reduction/wnn/sampling.py +0 -0
  357. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/reduction/wnn/umap_landmarks.py +0 -0
  358. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/repertoire/__init__.py +0 -0
  359. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/repertoire/analysis.py +0 -0
  360. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/repertoire/convergence.py +0 -0
  361. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/repertoire/distance.py +0 -0
  362. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/repertoire/plotting.py +0 -0
  363. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/repertoire/reference.py +0 -0
  364. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/__init__.py +0 -0
  365. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/datatype.py +0 -0
  366. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/download.py +0 -0
  367. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/log.py +0 -0
  368. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/method.py +0 -0
  369. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/methods/__init__.py +0 -0
  370. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/methods/aucell.py +0 -0
  371. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/methods/consensus.py +0 -0
  372. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/methods/decouple.py +0 -0
  373. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/methods/gsea.py +0 -0
  374. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/methods/gsva.py +0 -0
  375. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/methods/mdt.py +0 -0
  376. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/methods/mlm.py +0 -0
  377. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/methods/ora.py +0 -0
  378. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/methods/pv.py +0 -0
  379. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/methods/query_set.py +0 -0
  380. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/methods/registry.py +0 -0
  381. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/methods/run.py +0 -0
  382. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/methods/udt.py +0 -0
  383. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/methods/ulm.py +0 -0
  384. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/methods/viper.py +0 -0
  385. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/methods/waggr.py +0 -0
  386. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/methods/zscore.py +0 -0
  387. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/odeps.py +0 -0
  388. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/plotter.py +0 -0
  389. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/plotting/__init__.py +0 -0
  390. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/plotting/barplot.py +0 -0
  391. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/plotting/dotplot.py +0 -0
  392. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/plotting/filter_by_expr.py +0 -0
  393. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/plotting/filter_by_prop.py +0 -0
  394. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/plotting/filter_samples.py +0 -0
  395. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/plotting/leading_edge.py +0 -0
  396. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/plotting/network.py +0 -0
  397. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/plotting/obsbar.py +0 -0
  398. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/plotting/obsm.py +0 -0
  399. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/plotting/order.py +0 -0
  400. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/plotting/order_targets.py +0 -0
  401. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/plotting/source_targets.py +0 -0
  402. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/plotting/volcano.py +0 -0
  403. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/utils/__init__.py +0 -0
  404. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/utils/anndata.py +0 -0
  405. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/utils/data.py +0 -0
  406. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/utils/net.py +0 -0
  407. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/utils/rankby_group.py +0 -0
  408. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/utils/rankby_obsm.py +0 -0
  409. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/signature/utils/rankby_order.py +0 -0
  410. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/spatial/__init__.py +0 -0
  411. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/spatial/classifier.py +0 -0
  412. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/spatial/hd.py +0 -0
  413. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/spatial/interac.py +0 -0
  414. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/spatial/ligrec.py +0 -0
  415. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/spatial/mif.py +0 -0
  416. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/spatial/nhood.py +0 -0
  417. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/spatial/niche.py +0 -0
  418. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/spatial/ometiff.py +0 -0
  419. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/spatial/pattern.py +0 -0
  420. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/spatial/ripley.py +0 -0
  421. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/spatial/snn.py +0 -0
  422. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/spatial/tmap.py +0 -0
  423. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/spatial/utils.py +0 -0
  424. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/spatial/visium.py +0 -0
  425. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/spatial/xenium.py +0 -0
  426. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/trajectory/__init__.py +0 -0
  427. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/trajectory/cytotrace.py +0 -0
  428. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/trajectory/elpi.py +0 -0
  429. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/trajectory/pcurve.py +0 -0
  430. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/trajectory/pseudotime.py +0 -0
  431. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/trajectory/root.py +0 -0
  432. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/trajectory/trace.py +0 -0
  433. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/transfer/__init__.py +0 -0
  434. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/transfer/atlas.py +0 -0
  435. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/utils.py +0 -0
  436. {exprmat-0.2.79 → exprmat-0.2.81}/exprmat/wgcna/core.py +0 -0
  437. {exprmat-0.2.79 → exprmat-0.2.81}/license +0 -0
  438. {exprmat-0.2.79 → exprmat-0.2.81}/readme.md +0 -0
  439. {exprmat-0.2.79 → exprmat-0.2.81}/snapatac2/Cargo.toml +0 -0
  440. {exprmat-0.2.79 → exprmat-0.2.81}/snapatac2/license +0 -0
  441. {exprmat-0.2.79 → exprmat-0.2.81}/snapatac2/readme +0 -0
  442. {exprmat-0.2.79 → exprmat-0.2.81}/snapatac2/src/call_peaks.rs +0 -0
  443. {exprmat-0.2.79 → exprmat-0.2.81}/snapatac2/src/embedding.rs +0 -0
  444. {exprmat-0.2.79 → exprmat-0.2.81}/snapatac2/src/export.rs +0 -0
  445. {exprmat-0.2.79 → exprmat-0.2.81}/snapatac2/src/knn.rs +0 -0
  446. {exprmat-0.2.79 → exprmat-0.2.81}/snapatac2/src/lib.rs +0 -0
  447. {exprmat-0.2.79 → exprmat-0.2.81}/snapatac2/src/motif.rs +0 -0
  448. {exprmat-0.2.79 → exprmat-0.2.81}/snapatac2/src/network.rs +0 -0
  449. {exprmat-0.2.79 → exprmat-0.2.81}/snapatac2/src/preprocessing.rs +0 -0
  450. {exprmat-0.2.79 → exprmat-0.2.81}/snapatac2/src/utils/anndata.rs +0 -0
  451. {exprmat-0.2.79 → exprmat-0.2.81}/snapatac2/src/utils.rs +0 -0
  452. {exprmat-0.2.79 → exprmat-0.2.81}/snapatac2-core/Cargo.toml +0 -0
  453. {exprmat-0.2.79 → exprmat-0.2.81}/snapatac2-core/src/embedding.rs +0 -0
  454. {exprmat-0.2.79 → exprmat-0.2.81}/snapatac2-core/src/export.rs +0 -0
  455. {exprmat-0.2.79 → exprmat-0.2.81}/snapatac2-core/src/feature_count/counter.rs +0 -0
  456. {exprmat-0.2.79 → exprmat-0.2.81}/snapatac2-core/src/feature_count/data_iter.rs +0 -0
  457. {exprmat-0.2.79 → exprmat-0.2.81}/snapatac2-core/src/feature_count/matrix.rs +0 -0
  458. {exprmat-0.2.79 → exprmat-0.2.81}/snapatac2-core/src/feature_count/mod.rs +0 -0
  459. {exprmat-0.2.79 → exprmat-0.2.81}/snapatac2-core/src/genome.rs +0 -0
  460. {exprmat-0.2.79 → exprmat-0.2.81}/snapatac2-core/src/lib.rs +0 -0
  461. {exprmat-0.2.79 → exprmat-0.2.81}/snapatac2-core/src/motif.rs +0 -0
  462. {exprmat-0.2.79 → exprmat-0.2.81}/snapatac2-core/src/network.rs +0 -0
  463. {exprmat-0.2.79 → exprmat-0.2.81}/snapatac2-core/src/preprocessing/bam/flagstat.rs +0 -0
  464. {exprmat-0.2.79 → exprmat-0.2.81}/snapatac2-core/src/preprocessing/bam/header.rs +0 -0
  465. {exprmat-0.2.79 → exprmat-0.2.81}/snapatac2-core/src/preprocessing/bam/mark_duplicates.rs +0 -0
  466. {exprmat-0.2.79 → exprmat-0.2.81}/snapatac2-core/src/preprocessing/bam.rs +0 -0
  467. {exprmat-0.2.79 → exprmat-0.2.81}/snapatac2-core/src/preprocessing/import.rs +0 -0
  468. {exprmat-0.2.79 → exprmat-0.2.81}/snapatac2-core/src/preprocessing/mod.rs +0 -0
  469. {exprmat-0.2.79 → exprmat-0.2.81}/snapatac2-core/src/preprocessing/qc.rs +0 -0
  470. {exprmat-0.2.79 → exprmat-0.2.81}/snapatac2-core/src/utils/knn.rs +0 -0
  471. {exprmat-0.2.79 → exprmat-0.2.81}/snapatac2-core/src/utils/mod.rs +0 -0
  472. {exprmat-0.2.79 → exprmat-0.2.81}/snapatac2-core/src/utils/similarity.rs +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: exprmat
3
- Version: 0.2.79
3
+ Version: 0.2.81
4
4
  Classifier: Programming Language :: Rust
5
5
  Classifier: Programming Language :: Python :: Implementation :: CPython
6
6
  Classifier: Programming Language :: Python :: Implementation :: PyPy
@@ -106,6 +106,9 @@ default_finders = [
106
106
  'exprmat.config',
107
107
  '.exprmat.config',
108
108
  '.exprmatrc',
109
+ _os.path.join(str(_os.environ.get("CONDA_PREFIX") or ''), 'exprmat.config'),
110
+ _os.path.join(str(_os.environ.get("CONDA_PREFIX") or ''), '.exprmat.config'),
111
+ _os.path.join(str(_os.environ.get("CONDA_PREFIX") or ''), '.exprmatrc'),
109
112
  _os.path.join(str(_pathlib.Path.home()), 'exprmat.config'),
110
113
  _os.path.join(str(_pathlib.Path.home()), '.exprmat.config'),
111
114
  _os.path.join(str(_pathlib.Path.home()), '.exprmatrc')
@@ -0,0 +1,16 @@
1
+
2
+ from pandas import read_table, isnull
3
+ import pandas as pd
4
+ from numpy import unique
5
+ import numpy as np
6
+ import os
7
+ import itertools
8
+ from pandas import DataFrame
9
+
10
+ from exprmat.ansi import error, warning, info
11
+ from exprmat.data.finders import basepath
12
+
13
+
14
+ def get_malignancy_model_folder(taxa) -> DataFrame:
15
+ resource_path = os.path.join(basepath, taxa, 'malig')
16
+ return resource_path
@@ -25,7 +25,10 @@ def convert(genes):
25
25
  return frozendict(zip(genes, repeat(1.0)))
26
26
 
27
27
 
28
- @attr.s()
28
+ # `signature` must be hashable because `genes` and `weights` are memoized
29
+ # properties (`cytoolz.memoize` caches on the instance itself). without a
30
+ # generated `__hash__` any access to `signature.genes` raised a `TypeError`.
31
+ @attr.s(hash = True)
29
32
  class signature():
30
33
  """
31
34
  Gene signatures, i.e. a set of genes that are biologically related.
@@ -0,0 +1,45 @@
1
+ """
2
+ malignancy inference.
3
+
4
+ Malignant cells are distinguished from their normal counterparts using a
5
+ pretrained pan-cancer classifier, ported from `scMalignantFinder`
6
+ (https://github.com/Jonyyqn/scMalignantFinder, Yu et al., Commun Biol 2025).
7
+ Only human cancers can be predicted.
8
+
9
+ Only the inference part of the upstream package is included:
10
+
11
+ * :mod:`.classifier` -- pretrained cell-level (gross) malignancy inference.
12
+ * :mod:`.scoring` -- AUCell gene set scoring backed by the in-package
13
+ implementation in :mod:`exprmat.descriptive.aucell`.
14
+
15
+ Model training, scATOMIC cell type annotation (R) and spatial region
16
+ identification are not included, and no R, `scAtomic`, `pyscenic` or `ctxcore`
17
+ dependency is required.
18
+
19
+ The pretrained model (``model.joblib``) and its ordered feature list
20
+ (``ordered_feature.tsv``) are distributed separately by the upstream authors at
21
+ https://zenodo.org/records/17888140. Place both files in one directory and pass
22
+ it as ``pretrain_dir``.
23
+
24
+ Examples
25
+ --------
26
+ >>> from exprmat.malig import predict_malignancy
27
+ >>> adata = predict_malignancy(adata, pretrain_dir = 'pretrained_model')
28
+ >>> adata.obs[['malig', 'prob.malig']].head()
29
+ """
30
+
31
+ from exprmat.malig.classifier import (
32
+ malignancy_inference,
33
+ predict_malignancy,
34
+ load_ordered_features,
35
+ )
36
+
37
+ from exprmat.malig.scoring import aucell_score
38
+
39
+
40
+ __all__ = [
41
+ 'malignancy_inference',
42
+ 'predict_malignancy',
43
+ 'load_ordered_features',
44
+ 'aucell_score',
45
+ ]
@@ -0,0 +1,439 @@
1
+ """
2
+ cell-level (gross) malignancy inference with a pretrained model.
3
+
4
+ This module ports the inference half of `scMalignantFinder`
5
+ (https://github.com/Jonyyqn/scMalignantFinder, Yu et al., Commun Biol 2025).
6
+ Only the pretrained malignancy classifier is implemented. model training,
7
+ scATOMIC cell type annotation (which requires R) and spatial region
8
+ identification are intentionally left out, so this module has no dependency on
9
+ R, `scAtomic`, `pyscenic` or `ctxcore`.
10
+
11
+ .. warning::
12
+ The released model was trained on human pan-cancer signatures and is only
13
+ suitable for **human** data. Running it on mouse data, including after any
14
+ ortholog conversion, is strongly discouraged: malignant versus normal
15
+ expression programs are very unlikely to be conserved between species.
16
+ """
17
+
18
+ import os
19
+ from typing import Iterable
20
+
21
+ import joblib
22
+ import numpy as np
23
+ import pandas as pd
24
+ import scipy.sparse as sp
25
+ from anndata import AnnData
26
+
27
+ from exprmat.ansi import error, info, warning
28
+
29
+
30
+ MODEL_FILENAME = 'model.joblib'
31
+ FEATURE_FILENAME = 'ordered_feature.tsv'
32
+
33
+ NORMAL = 'Normal'
34
+ MALIGNANT = 'Malignant'
35
+
36
+ DEFAULT_TARGET_SUM = 1e4
37
+
38
+
39
+ def load_ordered_features(feature_path: str) -> list[str]:
40
+ """
41
+ Load an ordered feature list, one gene symbol per line.
42
+
43
+ The pretrained model expects the expression matrix to be arranged in exactly
44
+ this order. Duplicated entries are kept as they are, since the model was fit
45
+ on this exact layout.
46
+
47
+ Parameters
48
+ ----------
49
+ feature_path
50
+ Path to the feature list, usually ``ordered_feature.tsv``.
51
+
52
+ Returns
53
+ -------
54
+ The ordered list of feature (gene) names.
55
+ """
56
+
57
+ if not os.path.isfile(feature_path):
58
+ error(f'feature list not found: {feature_path}')
59
+
60
+ with open(feature_path, 'r') as f:
61
+ features = [line.strip() for line in f if line.strip()]
62
+
63
+ if len(features) == 0:
64
+ error(f'feature list is empty: {feature_path}')
65
+
66
+ return features
67
+
68
+
69
+ def _resolve_pretrain_files(
70
+ pretrain_dir: str | None = None,
71
+ model_path: str | None = None,
72
+ feature_path: str | None = None,
73
+ ) -> tuple[str, str]:
74
+
75
+ if pretrain_dir is not None:
76
+ if model_path is None:
77
+ model_path = os.path.join(pretrain_dir, MODEL_FILENAME)
78
+ if feature_path is None:
79
+ feature_path = os.path.join(pretrain_dir, FEATURE_FILENAME)
80
+
81
+ if model_path is None or feature_path is None:
82
+ error(
83
+ 'a pretrained model is required for inference. provide `pretrain_dir` '
84
+ f'(a directory containing `{MODEL_FILENAME}` and `{FEATURE_FILENAME}`), '
85
+ 'or provide both `model_path` and `feature_path`.'
86
+ )
87
+
88
+ return model_path, feature_path
89
+
90
+
91
+ def _expression_matrix(
92
+ adata: AnnData,
93
+ use_raw: bool = False,
94
+ layer: str | None = None,
95
+ ):
96
+
97
+ if use_raw and layer is not None:
98
+ error('`use_raw = True` and `layer` cannot be used together.')
99
+
100
+ if use_raw:
101
+ if adata.raw is None:
102
+ error('`use_raw = True`, but `adata.raw` is not available.')
103
+ X = adata.raw.X
104
+ var_names = adata.raw.var_names
105
+ elif layer is not None:
106
+ if layer not in adata.layers:
107
+ error(f'layer `{layer}` not found in `adata.layers`.')
108
+ X = adata.layers[layer]
109
+ var_names = adata.var_names
110
+ else:
111
+ X = adata.X
112
+ var_names = adata.var_names
113
+
114
+ if X is None:
115
+ error('the expression matrix is empty.')
116
+ if X.shape[0] != adata.n_obs:
117
+ error('the expression matrix does not match `adata.n_obs`.')
118
+
119
+ return X, var_names
120
+
121
+
122
+ def _feature_positions(
123
+ features: Iterable[str],
124
+ var_names: Iterable[str],
125
+ ) -> tuple[np.ndarray, np.ndarray, list[str]]:
126
+ """
127
+ Match the ordered model features against the variables of the expression
128
+ matrix. Returns the column positions in the output matrix, the corresponding
129
+ column indices in the expression matrix, and the missing feature names.
130
+ """
131
+
132
+ lookup: dict[str, int] = {}
133
+ for i, name in enumerate(var_names):
134
+ # keep the first occurrence, as `var_names_make_unique` does upstream.
135
+ lookup.setdefault(str(name), i)
136
+
137
+ cols: list[int] = []
138
+ idx: list[int] = []
139
+ missing: list[str] = []
140
+ for j, name in enumerate(features):
141
+ i = lookup.get(str(name))
142
+ if i is None:
143
+ missing.append(name)
144
+ else:
145
+ cols.append(j)
146
+ idx.append(i)
147
+
148
+ return (
149
+ np.asarray(cols, dtype = np.intp),
150
+ np.asarray(idx, dtype = np.intp),
151
+ missing,
152
+ )
153
+
154
+
155
+ class malignancy_inference():
156
+ """
157
+ Pretrained cell-level (gross) malignancy inference.
158
+
159
+ The classifier is trained on pan-cancer signatures by the
160
+ `scMalignantFinder` authors. This class only performs inference with the
161
+ released pretrained model: model training is not supported.
162
+
163
+ Parameters
164
+ ----------
165
+ pretrain_dir
166
+ Directory containing ``model.joblib`` and ``ordered_feature.tsv``.
167
+ model_path
168
+ Explicit path to a pretrained ``model.joblib``. Overrides
169
+ ``pretrain_dir`` when given.
170
+ feature_path
171
+ Explicit path to the ordered feature list. Overrides ``pretrain_dir``
172
+ when given.
173
+ normalize
174
+ Whether to apply library size normalization (to ``target_sum``) before
175
+ prediction. No log transformation is applied, as in the upstream
176
+ package. Set to ``False`` if the data are already normalized.
177
+ use_raw
178
+ Use ``adata.raw.X`` instead of ``adata.X``.
179
+ target_sum
180
+ Target total count per cell when ``normalize = True``.
181
+ verbose
182
+ Print information about the loaded model and missing features.
183
+
184
+ Examples
185
+ --------
186
+ >>> from exprmat.malig import malignancy_inference
187
+ >>> model = malignancy_inference(pretrain_dir = 'pretrained_model')
188
+ >>> model.load()
189
+ >>> adata = model.predict(adata)
190
+ """
191
+
192
+ def __init__(
193
+ self,
194
+ pretrain_dir: str | None = None,
195
+ model_path: str | None = None,
196
+ feature_path: str | None = None,
197
+ normalize: bool = True,
198
+ use_raw: bool = False,
199
+ target_sum: float = DEFAULT_TARGET_SUM,
200
+ verbose: bool = True,
201
+ ):
202
+
203
+ self.pretrain_dir = pretrain_dir
204
+ self.model_path = model_path
205
+ self.feature_path = feature_path
206
+
207
+ self.normalize = normalize
208
+ self.use_raw = use_raw
209
+ self.target_sum = float(target_sum)
210
+ self.verbose = verbose
211
+
212
+ self.model = None
213
+ self.features: list[str] | None = None
214
+ self.missing_features: list[str] = []
215
+
216
+ def load(self) -> 'malignancy_inference':
217
+ """
218
+ Load the pretrained model and the ordered feature list.
219
+ """
220
+
221
+ model_path, feature_path = _resolve_pretrain_files(
222
+ self.pretrain_dir, self.model_path, self.feature_path,
223
+ )
224
+
225
+ self.model_path = model_path
226
+ self.feature_path = feature_path
227
+
228
+ if not os.path.isfile(model_path):
229
+ error(f'pretrained model not found: {model_path}')
230
+
231
+ try:
232
+ self.model = joblib.load(model_path)
233
+ except ImportError as e:
234
+ error(
235
+ 'failed to load the pretrained model. the model may depend on a '
236
+ 'package that is not installed (for example `xgboost`).',
237
+ error = e,
238
+ )
239
+
240
+ if not hasattr(self.model, 'predict_proba'):
241
+ error('the loaded model does not provide `predict_proba`.')
242
+
243
+ self.features = load_ordered_features(feature_path)
244
+
245
+ n_expected = getattr(self.model, 'n_features_in_', None)
246
+ if n_expected is not None and int(n_expected) != len(self.features):
247
+ warning(
248
+ f'the model expects {int(n_expected)} features, but the feature '
249
+ f'list contains {len(self.features)} entries.'
250
+ )
251
+
252
+ if self.verbose:
253
+ info(
254
+ 'loaded pretrained malignancy model '
255
+ f'({type(self.model).__name__}, {len(self.features)} features).'
256
+ )
257
+
258
+ return self
259
+
260
+ def predict(
261
+ self,
262
+ adata: AnnData,
263
+ layer: str | None = None,
264
+ copy: bool = False,
265
+ key_prediction: str = 'malig',
266
+ key_probability: str = 'prob.malig',
267
+ ) -> AnnData:
268
+ """
269
+ Predict malignancy for each observation.
270
+
271
+ Parameters
272
+ ----------
273
+ adata
274
+ Annotated data matrix with genes as variables and cells as
275
+ observations.
276
+ layer
277
+ Use ``adata.layers[layer]`` as the expression matrix. Cannot be
278
+ combined with ``use_raw = True``.
279
+ copy
280
+ Return a copy instead of writing to ``adata`` in place.
281
+ key_prediction
282
+ ``adata.obs`` key for the predicted label, either ``Normal`` or
283
+ ``Malignant``. Default ``'malig'``.
284
+ key_probability
285
+ ``adata.obs`` key for the probability of being malignant.
286
+ Default ``'prob.malig'``.
287
+
288
+ Returns
289
+ -------
290
+ The ``AnnData`` object with predictions added to ``.obs``.
291
+ """
292
+
293
+ if not isinstance(adata, AnnData):
294
+ error(f'`adata` must be an AnnData object, got {type(adata).__name__}.')
295
+
296
+ if self.model is None or self.features is None:
297
+ self.load()
298
+
299
+ X, var_names = _expression_matrix(
300
+ adata, use_raw = self.use_raw, layer = layer,
301
+ )
302
+
303
+ n_features = len(self.features)
304
+ cols, idx, missing = _feature_positions(self.features, var_names)
305
+ self.missing_features = missing
306
+
307
+ if self.verbose and len(missing) > 0:
308
+ pct = 100.0 * len(missing) / n_features
309
+ warning(
310
+ f'{len(missing)} of {n_features} model features ({pct:.2f}%) are '
311
+ 'absent from the data and are imputed as zero.'
312
+ )
313
+ if pct > 20:
314
+ warning(
315
+ 'more than 20% of the model features are missing. '
316
+ 'prediction quality may be compromised.'
317
+ )
318
+
319
+ # build the feature matrix in the exact order expected by the model.
320
+ if len(idx) > 0:
321
+ sub = X[:, idx]
322
+ if sp.issparse(sub): sub = sub.toarray()
323
+ sub = np.asarray(sub)
324
+ dtype = np.result_type(sub.dtype, np.float32)
325
+ else:
326
+ sub = None
327
+ dtype = np.float64
328
+
329
+ dense = np.zeros((adata.n_obs, n_features), dtype = dtype)
330
+ if sub is not None:
331
+ dense[:, cols] = sub
332
+ del sub
333
+
334
+ # per-cell library size normalization. because the scaling factor is
335
+ # constant per cell it is equivalent to normalizing the full matrix
336
+ # first, but much cheaper.
337
+ if self.normalize:
338
+ totals = np.asarray(X.sum(axis = 1)).ravel()
339
+ scale = np.zeros(totals.shape, dtype = np.float64)
340
+ np.divide(self.target_sum, totals, out = scale, where = totals > 0)
341
+ dense *= scale[:, None]
342
+
343
+ proba = np.asarray(self.model.predict_proba(dense))
344
+ column = self._positive_index()
345
+
346
+ probability = proba.ravel() if proba.ndim == 1 else proba[:, column]
347
+ labels = np.asarray(self.model.predict(dense)).ravel()
348
+
349
+ classes = list(getattr(self.model, 'classes_', [0, 1]))
350
+ positive = classes[column] if column < len(classes) else 1
351
+ malignant = labels == positive
352
+
353
+ out = adata.copy() if copy else adata
354
+ out.obs[key_prediction] = pd.Categorical(
355
+ np.where(malignant, MALIGNANT, NORMAL),
356
+ categories = [NORMAL, MALIGNANT],
357
+ )
358
+ out.obs[key_probability] = probability.astype(np.float64)
359
+
360
+ return out
361
+
362
+ def _positive_index(self) -> int:
363
+ """
364
+ Column of ``predict_proba`` corresponding to the malignant class (label 1).
365
+ """
366
+
367
+ classes = list(getattr(self.model, 'classes_', [0, 1]))
368
+ if 1 in classes: return classes.index(1)
369
+ return len(classes) - 1
370
+
371
+
372
+ def predict_malignancy(
373
+ adata: AnnData,
374
+ pretrain_dir: str | None = None,
375
+ model_path: str | None = None,
376
+ feature_path: str | None = None,
377
+ normalize: bool = True,
378
+ use_raw: bool = False,
379
+ layer: str | None = None,
380
+ target_sum: float = DEFAULT_TARGET_SUM,
381
+ copy: bool = False,
382
+ key_prediction: str = 'malig',
383
+ key_probability: str = 'prob.malig',
384
+ verbose: bool = True,
385
+ ) -> AnnData:
386
+ """
387
+ Predict cell-level malignancy with a pretrained `scMalignantFinder` model.
388
+
389
+ This is a convenience wrapper around :class:`malignancy_inference`. Use the
390
+ class directly if you want to reuse the loaded model for several datasets.
391
+
392
+ Parameters
393
+ ----------
394
+ adata
395
+ Annotated data matrix with genes as variables and cells as observations.
396
+ pretrain_dir
397
+ Directory containing ``model.joblib`` and ``ordered_feature.tsv``.
398
+ model_path
399
+ Explicit path to a pretrained ``model.joblib``.
400
+ feature_path
401
+ Explicit path to the ordered feature list.
402
+ normalize
403
+ Apply library size normalization to ``target_sum`` before prediction.
404
+ use_raw
405
+ Use ``adata.raw.X`` instead of ``adata.X``.
406
+ layer
407
+ Use ``adata.layers[layer]`` instead of ``adata.X``.
408
+ target_sum
409
+ Target total count per cell when ``normalize = True``.
410
+ copy
411
+ Return a copy instead of writing to ``adata`` in place.
412
+ key_prediction
413
+ ``adata.obs`` key for the predicted label. Default ``'malig'``.
414
+ key_probability
415
+ ``adata.obs`` key for the malignancy probability. Default ``'prob.malig'``.
416
+ verbose
417
+ Print information about the loaded model and missing features.
418
+
419
+ Returns
420
+ -------
421
+ The ``AnnData`` object with predictions added to ``.obs``.
422
+ """
423
+
424
+ model = malignancy_inference(
425
+ pretrain_dir = pretrain_dir,
426
+ model_path = model_path,
427
+ feature_path = feature_path,
428
+ normalize = normalize,
429
+ use_raw = use_raw,
430
+ target_sum = target_sum,
431
+ verbose = verbose,
432
+ )
433
+
434
+ model.load()
435
+ return model.predict(
436
+ adata, layer = layer, copy = copy,
437
+ key_prediction = key_prediction,
438
+ key_probability = key_probability,
439
+ )
@@ -0,0 +1,156 @@
1
+ """
2
+ gene set scoring utilities for malignant signatures.
3
+
4
+ The upstream `scMalignantFinder` implements its AUCell helper on top of
5
+ `pyscenic.aucell` and `ctxcore.genesig.GeneSignature`. This module uses the
6
+ in-package AUCell implementation (:mod:`exprmat.descriptive.aucell`) and the
7
+ in-package signature type (:class:`exprmat.data.signature.signature`) instead,
8
+ so neither `pyscenic` nor `ctxcore` is required.
9
+ """
10
+
11
+ import numpy as np
12
+ from anndata import AnnData
13
+
14
+ from exprmat.ansi import error, warning
15
+ from exprmat.data.signature import signature
16
+ from exprmat.descriptive.aucell import aucell, derive_auc_threshold
17
+
18
+
19
+ def aucell_score(
20
+ adata: AnnData,
21
+ gmt: str,
22
+ layer: str | None = None,
23
+ normalize_total: bool = False,
24
+ target_sum: float = 1e4,
25
+ adapt_signatures: bool = True,
26
+ min_overlap: float = 0.5,
27
+ auc_threshold: float | None = None,
28
+ seed: int | None = 2,
29
+ num_workers: int = 1,
30
+ key_added: str | None = None,
31
+ copy: bool = False,
32
+ ) -> AnnData:
33
+ """
34
+ Calculate per-observation AUCell scores for the gene sets in a gmt file.
35
+
36
+ This mirrors ``scMalignantFinder.utils.aucell_cal`` but is backed by the
37
+ in-package AUCell implementation. Scores are normalized to a maximum of 1.0
38
+ per gene set, as upstream.
39
+
40
+ .. note::
41
+ The expression matrix is densified internally, so this helper is intended
42
+ for a biologically relevant subset of cells.
43
+
44
+ Parameters
45
+ ----------
46
+ adata
47
+ Annotated data matrix with genes as variables and cells as observations.
48
+ gmt
49
+ Path to a gene set file in gmt format.
50
+ layer
51
+ Use ``adata.layers[layer]`` as the expression matrix. Defaults to
52
+ ``adata.X``.
53
+ normalize_total
54
+ Normalize total counts to ``target_sum`` per cell before scoring. The
55
+ input ``adata`` is not modified.
56
+ target_sum
57
+ Target total count per cell when ``normalize_total = True``.
58
+ adapt_signatures
59
+ Drop gene sets whose overlap with the variables of the data is below
60
+ ``min_overlap``. Without this, sets composed mostly of absent genes
61
+ would be scored as (near) zero.
62
+ min_overlap
63
+ Minimum fraction of genes of a set that must be present in the data.
64
+ auc_threshold
65
+ Fraction of the ranked genome to use for the AUC. Defaults to the 1%
66
+ quantile of detected genes, as derived by
67
+ :func:`exprmat.descriptive.aucell.derive_auc_threshold`.
68
+ seed
69
+ Seed used when shuffling the expression matrix before ranking.
70
+ num_workers
71
+ Number of worker processes used for the AUC computation.
72
+ key_added
73
+ If ``None`` (default), one column per gene set is added to ``adata.obs``.
74
+ Otherwise, scores are stored in ``adata.obsm[key_added]`` and the gene
75
+ set names in ``adata.uns['{key_added}.genesets']``.
76
+ copy
77
+ Return a copy instead of writing to ``adata`` in place.
78
+
79
+ Returns
80
+ -------
81
+ The ``AnnData`` object with the scores added.
82
+ """
83
+
84
+ if not isinstance(adata, AnnData):
85
+ error(f'`adata` must be an AnnData object, got {type(adata).__name__}.')
86
+
87
+ if not isinstance(gmt, str):
88
+ error('`gmt` must be a path to a gmt file.')
89
+
90
+ signatures = signature.from_gmt(
91
+ gmt, field_separator = '\t', gene_separator = '\t',
92
+ )
93
+
94
+ gene_names = set(map(str, adata.var_names))
95
+
96
+ if adapt_signatures:
97
+ kept = []
98
+ for s in signatures:
99
+ overlap = len(set(map(str, s.gene2weight)) & gene_names) / len(s)
100
+ if overlap >= min_overlap: kept.append(s)
101
+
102
+ if len(kept) == 0:
103
+ error(
104
+ f'none of the {len(signatures)} gene sets in `{gmt}` overlap with '
105
+ f'at least {min_overlap:.0%} of the variables of the data.'
106
+ )
107
+
108
+ if len(kept) < len(signatures):
109
+ warning(
110
+ f'{len(signatures) - len(kept)} of {len(signatures)} gene sets '
111
+ f'were dropped (< {min_overlap:.0%} overlap with the data).'
112
+ )
113
+
114
+ signatures = kept
115
+
116
+ if len(signatures) == 0:
117
+ error(f'no usable gene sets found in `{gmt}`.')
118
+
119
+ names = [str(s.name) for s in signatures]
120
+ if len(set(names)) != len(names):
121
+ warning('duplicated gene set names in the gmt file; scores will collide.')
122
+
123
+ # the expression matrix as a dense (cell x gene) dataframe, which is what
124
+ # the ranking based AUCell implementation expects.
125
+ df = adata.to_df(layer = layer)
126
+
127
+ if normalize_total:
128
+ totals = df.sum(axis = 1).to_numpy(dtype = np.float64)
129
+ scale = np.zeros(totals.shape, dtype = np.float64)
130
+ np.divide(float(target_sum), totals, out = scale, where = totals > 0)
131
+ df = df.mul(scale, axis = 0)
132
+
133
+ if auc_threshold is None:
134
+ auc_threshold = float(derive_auc_threshold(df)[0.01])
135
+
136
+ scores = aucell(
137
+ df, signatures,
138
+ auc_threshold = auc_threshold,
139
+ normalize = True,
140
+ seed = seed,
141
+ num_workers = num_workers,
142
+ )
143
+
144
+ # keep the original observation order.
145
+ scores = scores.reindex(adata.obs_names)
146
+
147
+ out = adata.copy() if copy else adata
148
+
149
+ if key_added is None:
150
+ for i, name in enumerate(scores.columns):
151
+ out.obs[str(name)] = scores.iloc[:, i].to_numpy()
152
+ else:
153
+ out.obsm[key_added] = scores.to_numpy()
154
+ out.uns[f'{key_added}.genesets'] = list(map(str, scores.columns))
155
+
156
+ return out