exprmat 0.1.28__tar.gz → 0.1.30__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 (168) hide show
  1. {exprmat-0.1.28 → exprmat-0.1.30}/PKG-INFO +4 -2
  2. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/__init__.py +13 -6
  3. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/clustering/seriation.py +4 -3
  4. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/data/finders.py +1 -1
  5. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/descriptive/kde.py +6 -3
  6. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/dynamics/preprocess.py +0 -1
  7. exprmat-0.1.30/exprmat/plotting/cnmf.py +154 -0
  8. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/plotting/expression.py +4 -3
  9. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/plotting/track.py +52 -2
  10. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/preprocessing/integrate.py +16 -9
  11. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/reader/experiment.py +5 -6
  12. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/reader/metadata.py +21 -8
  13. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/reader/static.py +15 -2
  14. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/utils.py +22 -0
  15. {exprmat-0.1.28 → exprmat-0.1.30}/pyproject.toml +4 -2
  16. exprmat-0.1.28/exprmat/plotting/cnmf.py +0 -66
  17. {exprmat-0.1.28 → exprmat-0.1.30}/Cargo.lock +0 -0
  18. {exprmat-0.1.28 → exprmat-0.1.30}/Cargo.toml +0 -0
  19. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/ansi.py +0 -0
  20. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/clustering/__init__.py +0 -0
  21. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/clustering/cnmf.py +0 -0
  22. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/clustering/dbscan.py +0 -0
  23. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/clustering/kmeans.py +0 -0
  24. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/clustering/leiden.py +0 -0
  25. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/clustering/nmf.py +0 -0
  26. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/clustering/rogue.py +0 -0
  27. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/clustering/spectral.py +0 -0
  28. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/clustering/utils.py +0 -0
  29. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/cnv/__init__.py +0 -0
  30. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/cnv/cnvscore.py +0 -0
  31. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/cnv/infercnv.py +0 -0
  32. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/configuration.py +0 -0
  33. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/data/__init__.py +0 -0
  34. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/data/cistarget.py +0 -0
  35. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/data/delim.py +0 -0
  36. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/data/geneset.py +0 -0
  37. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/data/gff.py +0 -0
  38. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/data/io.py +0 -0
  39. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/data/lr.py +0 -0
  40. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/data/presets.py +0 -0
  41. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/data/private.py +0 -0
  42. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/data/ranges.py +0 -0
  43. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/data/signature.py +0 -0
  44. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/data/tf.py +0 -0
  45. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/descriptive/__init__.py +0 -0
  46. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/descriptive/aggregate.py +0 -0
  47. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/descriptive/atac.py +0 -0
  48. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/descriptive/aucell.py +0 -0
  49. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/descriptive/de.py +0 -0
  50. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/descriptive/gse.py +0 -0
  51. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/descriptive/recovery.py +0 -0
  52. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/descriptive/summary.py +0 -0
  53. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/descriptive/tcr.py +0 -0
  54. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/dynamics/__init__.py +0 -0
  55. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/dynamics/generank.py +0 -0
  56. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/dynamics/linreg.py +0 -0
  57. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/dynamics/moments.py +0 -0
  58. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/dynamics/optimization.py +0 -0
  59. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/dynamics/parallel.py +0 -0
  60. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/dynamics/pseudotime.py +0 -0
  61. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/dynamics/transition.py +0 -0
  62. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/dynamics/utils.py +0 -0
  63. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/dynamics/velocity.py +0 -0
  64. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/grn/__init__.py +0 -0
  65. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/grn/infergrn.py +0 -0
  66. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/grn/modules.py +0 -0
  67. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/grn/prune.py +0 -0
  68. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/grn/regressors.py +0 -0
  69. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/grn/utils.py +0 -0
  70. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/lr/__init__.py +0 -0
  71. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/lr/aggregate.py +0 -0
  72. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/lr/method.py +0 -0
  73. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/lr/methods/__init__.py +0 -0
  74. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/lr/methods/cellchat.py +0 -0
  75. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/lr/methods/cellphonedb.py +0 -0
  76. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/lr/methods/connectome.py +0 -0
  77. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/lr/methods/geomean.py +0 -0
  78. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/lr/methods/logfc.py +0 -0
  79. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/lr/methods/natmi.py +0 -0
  80. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/lr/methods/rank_aggregate.py +0 -0
  81. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/lr/methods/scseqcomm.py +0 -0
  82. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/lr/methods/singlecellsignalr.py +0 -0
  83. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/lr/pipeline.py +0 -0
  84. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/lr/preprocess.py +0 -0
  85. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/lr/resources.py +0 -0
  86. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/lr/utils.py +0 -0
  87. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/plotting/__init__.py +0 -0
  88. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/plotting/atac.py +0 -0
  89. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/plotting/cnv.py +0 -0
  90. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/plotting/de.py +0 -0
  91. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/plotting/gse.py +0 -0
  92. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/plotting/lr.py +0 -0
  93. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/plotting/palettes.py +0 -0
  94. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/plotting/sankey.py +0 -0
  95. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/plotting/summary.py +0 -0
  96. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/plotting/utils.py +0 -0
  97. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/plotting/velocity.py +0 -0
  98. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/preprocessing/__init__.py +0 -0
  99. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/preprocessing/doublets/__init__.py +0 -0
  100. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/preprocessing/doublets/composite.py +0 -0
  101. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/preprocessing/doublets/scrublet.py +0 -0
  102. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/preprocessing/emptydrops.py +0 -0
  103. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/preprocessing/filter.py +0 -0
  104. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/preprocessing/impute/__init__.py +0 -0
  105. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/preprocessing/impute/magic.py +0 -0
  106. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/preprocessing/linear.py +0 -0
  107. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/preprocessing/normal.py +0 -0
  108. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/preprocessing/plot.py +0 -0
  109. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/preprocessing/qc.py +0 -0
  110. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/preprocessing/sctransform/__init__.py +0 -0
  111. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/preprocessing/sctransform/estimate.py +0 -0
  112. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/preprocessing/sctransform/ksmooth.py +0 -0
  113. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/preprocessing/sctransform/residual.py +0 -0
  114. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/preprocessing/sctransform/transform.py +0 -0
  115. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/preprocessing/sparse.py +0 -0
  116. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/preprocessing/uniform.py +0 -0
  117. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/reader/__init__.py +0 -0
  118. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/reader/matcher.py +0 -0
  119. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/reader/peaks.py +0 -0
  120. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/reduction/__init__.py +0 -0
  121. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/reduction/forceatlas.py +0 -0
  122. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/reduction/mde.py +0 -0
  123. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/reduction/nn.py +0 -0
  124. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/reduction/outliers.py +0 -0
  125. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/reduction/pca.py +0 -0
  126. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/reduction/plot.py +0 -0
  127. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/reduction/spectral.py +0 -0
  128. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/reduction/tsne.py +0 -0
  129. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/reduction/umap.py +0 -0
  130. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/trajectory/pcurve.py +0 -0
  131. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/transfer/__init__.py +0 -0
  132. {exprmat-0.1.28 → exprmat-0.1.30}/exprmat/transfer/atlas.py +0 -0
  133. {exprmat-0.1.28 → exprmat-0.1.30}/license +0 -0
  134. {exprmat-0.1.28 → exprmat-0.1.30}/readme.md +0 -0
  135. {exprmat-0.1.28 → exprmat-0.1.30}/snapatac2/Cargo.toml +0 -0
  136. {exprmat-0.1.28 → exprmat-0.1.30}/snapatac2/license +0 -0
  137. {exprmat-0.1.28 → exprmat-0.1.30}/snapatac2/readme +0 -0
  138. {exprmat-0.1.28 → exprmat-0.1.30}/snapatac2/src/call_peaks.rs +0 -0
  139. {exprmat-0.1.28 → exprmat-0.1.30}/snapatac2/src/embedding.rs +0 -0
  140. {exprmat-0.1.28 → exprmat-0.1.30}/snapatac2/src/export.rs +0 -0
  141. {exprmat-0.1.28 → exprmat-0.1.30}/snapatac2/src/knn.rs +0 -0
  142. {exprmat-0.1.28 → exprmat-0.1.30}/snapatac2/src/lib.rs +0 -0
  143. {exprmat-0.1.28 → exprmat-0.1.30}/snapatac2/src/motif.rs +0 -0
  144. {exprmat-0.1.28 → exprmat-0.1.30}/snapatac2/src/network.rs +0 -0
  145. {exprmat-0.1.28 → exprmat-0.1.30}/snapatac2/src/preprocessing.rs +0 -0
  146. {exprmat-0.1.28 → exprmat-0.1.30}/snapatac2/src/utils/anndata.rs +0 -0
  147. {exprmat-0.1.28 → exprmat-0.1.30}/snapatac2/src/utils.rs +0 -0
  148. {exprmat-0.1.28 → exprmat-0.1.30}/snapatac2-core/Cargo.toml +0 -0
  149. {exprmat-0.1.28 → exprmat-0.1.30}/snapatac2-core/src/embedding.rs +0 -0
  150. {exprmat-0.1.28 → exprmat-0.1.30}/snapatac2-core/src/export.rs +0 -0
  151. {exprmat-0.1.28 → exprmat-0.1.30}/snapatac2-core/src/feature_count/counter.rs +0 -0
  152. {exprmat-0.1.28 → exprmat-0.1.30}/snapatac2-core/src/feature_count/data_iter.rs +0 -0
  153. {exprmat-0.1.28 → exprmat-0.1.30}/snapatac2-core/src/feature_count/matrix.rs +0 -0
  154. {exprmat-0.1.28 → exprmat-0.1.30}/snapatac2-core/src/feature_count/mod.rs +0 -0
  155. {exprmat-0.1.28 → exprmat-0.1.30}/snapatac2-core/src/genome.rs +0 -0
  156. {exprmat-0.1.28 → exprmat-0.1.30}/snapatac2-core/src/lib.rs +0 -0
  157. {exprmat-0.1.28 → exprmat-0.1.30}/snapatac2-core/src/motif.rs +0 -0
  158. {exprmat-0.1.28 → exprmat-0.1.30}/snapatac2-core/src/network.rs +0 -0
  159. {exprmat-0.1.28 → exprmat-0.1.30}/snapatac2-core/src/preprocessing/bam/flagstat.rs +0 -0
  160. {exprmat-0.1.28 → exprmat-0.1.30}/snapatac2-core/src/preprocessing/bam/header.rs +0 -0
  161. {exprmat-0.1.28 → exprmat-0.1.30}/snapatac2-core/src/preprocessing/bam/mark_duplicates.rs +0 -0
  162. {exprmat-0.1.28 → exprmat-0.1.30}/snapatac2-core/src/preprocessing/bam.rs +0 -0
  163. {exprmat-0.1.28 → exprmat-0.1.30}/snapatac2-core/src/preprocessing/import.rs +0 -0
  164. {exprmat-0.1.28 → exprmat-0.1.30}/snapatac2-core/src/preprocessing/mod.rs +0 -0
  165. {exprmat-0.1.28 → exprmat-0.1.30}/snapatac2-core/src/preprocessing/qc.rs +0 -0
  166. {exprmat-0.1.28 → exprmat-0.1.30}/snapatac2-core/src/utils/knn.rs +0 -0
  167. {exprmat-0.1.28 → exprmat-0.1.30}/snapatac2-core/src/utils/mod.rs +0 -0
  168. {exprmat-0.1.28 → exprmat-0.1.30}/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.1.28
3
+ Version: 0.1.30
4
4
  Classifier: Programming Language :: Rust
5
5
  Classifier: Programming Language :: Python :: Implementation :: CPython
6
6
  Classifier: Programming Language :: Python :: Implementation :: PyPy
@@ -54,7 +54,9 @@ Requires-Dist: multiprocessing-on-dill
54
54
  Requires-Dist: pysam
55
55
  Requires-Dist: hdbscan
56
56
  Requires-Dist: graphtools
57
- Requires-Dist: bincsync
57
+ Requires-Dist: bincsync>=0.3.0
58
+ Requires-Dist: pybigwig
59
+ Requires-Dist: loompy
58
60
  Requires-Dist: sphinx ; extra == 'dev'
59
61
  Requires-Dist: sphinx-rtd-theme ; extra == 'dev'
60
62
  Requires-Dist: twine ; extra == 'dev'
@@ -10,15 +10,10 @@ import anndata as ad
10
10
  import scanpy as sc
11
11
  import pathlib
12
12
 
13
- # core method exports
14
- from exprmat.utils import setup_styles
15
- from exprmat.reader.experiment import experiment, load_experiment
16
- from exprmat.reader.metadata import metadata, load_metadata
17
13
  from exprmat.configuration import default as config
18
14
  from exprmat.ansi import warning, info
19
15
 
20
16
  mu.set_options(pull_on_update = False)
21
- setup_styles()
22
17
 
23
18
 
24
19
  DATABASE_SETUP_MESSAGE = """
@@ -44,11 +39,22 @@ default_finders = [
44
39
 
45
40
  for finder in default_finders:
46
41
  if os.path.exists(finder):
47
- info(f'load configuration from {finder}.')
42
+ info(f'load configuration from {finder}')
48
43
  with open(finder, 'r') as f:
49
44
  import json
50
45
  workspace_config = json.load(f)
51
46
  config.update(workspace_config)
47
+ break
48
+
49
+ basepath = config['data']
50
+
51
+ # core method exports
52
+ from exprmat.utils import setup_styles
53
+ from exprmat.reader.experiment import experiment, load_experiment
54
+ from exprmat.reader.metadata import metadata, load_metadata
55
+
56
+ setup_styles()
57
+
52
58
 
53
59
  def version_db():
54
60
  dbpath = config['data']
@@ -62,6 +68,7 @@ def version_db():
62
68
 
63
69
  return db_ver
64
70
 
71
+
65
72
  # perform database integrity check.
66
73
  if PERFORM_DATABASE_CHECK:
67
74
  db_ver = version_db()
@@ -31,7 +31,7 @@ def seriation(Z, N, cur_index):
31
31
  return (seriation(Z, N, left) + seriation(Z, N, right))
32
32
 
33
33
 
34
- def serial_matrix(dist, method = "ward"):
34
+ def serial_matrix(dist, method = "ward", seed = 42):
35
35
  '''
36
36
  Compute_serial_matrix transforms a distance matrix into a sorted distance matrix
37
37
  according to the order implied by the hierarchical tree (dendrogram).
@@ -51,13 +51,14 @@ def serial_matrix(dist, method = "ward"):
51
51
  - res_order: The order implied by the hierarhical tree
52
52
  - res_linkage: The hierarhical tree (dendrogram)
53
53
  '''
54
+ np.random.seed(seed)
54
55
 
55
56
  N = len(dist)
56
57
  flat_dist_mat = squareform(dist)
57
- res_linkage = linkage(flat_dist_mat, method=method,preserve_input=True)
58
+ res_linkage = linkage(flat_dist_mat, method = method,preserve_input = True)
58
59
  res_order = seriation(res_linkage, N, N + N-2)
59
60
  seriated_dist = np.zeros((N,N))
60
- a,b = np.triu_indices(N,k=1)
61
+ a,b = np.triu_indices(N, k = 1)
61
62
  seriated_dist[a,b] = dist[ [res_order[i] for i in a], [res_order[j] for j in b]]
62
63
  seriated_dist[b,a] = seriated_dist[a,b]
63
64
 
@@ -1,10 +1,10 @@
1
1
 
2
2
  import os
3
3
  import pandas
4
+ from exprmat import basepath
4
5
  from exprmat.ansi import warning, info
5
6
  from exprmat.configuration import default as cfg
6
7
 
7
- basepath = cfg['data']
8
8
  genome = {}
9
9
 
10
10
  def refresh_genome():
@@ -100,9 +100,12 @@ def density(
100
100
  cat_mask = adata.obs[groupby] == cat
101
101
  embed_x = adata.obsm[f"{basis}"][cat_mask, components[0]]
102
102
  embed_y = adata.obsm[f"{basis}"][cat_mask, components[1]]
103
-
104
- dens_embed = kde(embed_x, embed_y)
105
- density_values[cat_mask] = dens_embed
103
+ n, = embed_x.shape
104
+ if n <= 5:
105
+ density_values[cat_mask] = 1 / n
106
+ else:
107
+ dens_embed = kde(embed_x, embed_y)
108
+ density_values[cat_mask] = dens_embed
106
109
 
107
110
  adata.obs[density_covariate] = density_values
108
111
 
@@ -5,7 +5,6 @@ import pandas as pd
5
5
  from scipy.sparse import issparse
6
6
  from sklearn.utils import sparsefuncs
7
7
 
8
- from scvelo.core import get_initial_size, set_initial_size
9
8
  from exprmat.preprocessing import normalize, log1p
10
9
  from exprmat.dynamics.generank import get_mean_var
11
10
  from exprmat.dynamics.linreg import sum, multiply
@@ -0,0 +1,154 @@
1
+
2
+ import matplotlib.pyplot as plt
3
+ import pandas as pd
4
+
5
+
6
+ def cnmf_silhoutte(adata, nmf_slot = 'cnmf', figsize = (3, 2), dpi = 100):
7
+
8
+ fig = plt.figure(figsize = figsize, dpi = dpi)
9
+ df = adata.uns[f'{nmf_slot}.stats']
10
+ fig.gca().plot(df.ncomps, df.silhoutte, color = 'k')
11
+
12
+ # fig.gca().set_ylim([-0.1, 1.1])
13
+ # fig.gca().set_yticks([0, 0.25, 0.5, 0.75, 1])
14
+ fig.gca().set_ylabel('Silhoutte score')
15
+
16
+ fig.gca().set_xlabel('NMF components')
17
+ fig.gca().set_xticks(df.ncomps)
18
+
19
+ for pos in ['right', 'top']:
20
+ fig.gca().spines[pos].set_visible(False)
21
+
22
+ return fig
23
+
24
+
25
+ def cnmf_density(adata, k, nmf_slot = 'cnmf', figsize = (3, 2), dpi = 100):
26
+
27
+ fig = plt.figure(figsize = figsize, dpi = dpi)
28
+ df = adata.uns[f'{nmf_slot}.density.{k}']
29
+ fig.gca().hist(df, bins = 100, color = 'k')
30
+
31
+ fig.gca().set_ylabel('Local density')
32
+ fig.gca().set_xlabel('Distance')
33
+
34
+ for pos in ['right', 'top']:
35
+ fig.gca().spines[pos].set_visible(False)
36
+
37
+ return fig
38
+
39
+
40
+ def cnmf_distance_comps(adata, k, nmf_slot = 'cnmf', cmap = 'Reds_r', figsize = (3, 3), dpi = 100):
41
+
42
+ fig = plt.figure(figsize = figsize, dpi = dpi)
43
+ df = adata.uns[f'{nmf_slot}.dist.{k}']
44
+ fig.gca().imshow(df, cmap = cmap)
45
+
46
+ return fig
47
+
48
+
49
+ def cnmf_distance_usages(
50
+ adata, k, nmf_slot = 'cnmf', metrics = 'cosine', downsample = 0.1, method = 'single',
51
+ annotations = None, show_indices = False, legend_cols = 1,
52
+ cmap = 'Reds_r', cmap_annotations = 'Set1', figsize = (3, 3), dpi = 100
53
+ ):
54
+
55
+ import numpy as np
56
+
57
+ df = adata.obsm[f'{nmf_slot}.{k}']
58
+ nrow = df.shape[0]
59
+ subset = np.random.choice(range(nrow), int(nrow * downsample), replace = False)
60
+ from exprmat.clustering.seriation import pdist
61
+ data = df.iloc[subset, :].copy()
62
+ pdistc = pdist(data, metric = metrics)
63
+
64
+ from exprmat.clustering.seriation import serial_matrix, squareform
65
+ serial, order, _ = serial_matrix(squareform(pdistc), method = method)
66
+ indices = adata.obs.iloc[subset, :].iloc[order, :].index.tolist()
67
+ if annotations: annotations = adata.obs.iloc[subset, :].iloc[order, :][annotations].tolist()
68
+
69
+ return matrix_plot(
70
+ serial, labels = indices, annotations = annotations, cmap_annotations = cmap_annotations,
71
+ cmap = cmap, figsize = figsize, dpi = dpi, show_indices = show_indices,
72
+ legend_cols = legend_cols
73
+ )
74
+
75
+
76
+ def cnmf_distance_modules(
77
+ adata, k, nmf_slot = 'cnmf', metrics = 'cosine', downsample = 1, method = 'complete',
78
+ annotations = None, cmap_annotations = 'Set1', show_indices = False,
79
+ cmap = 'Reds_r', figsize = (3, 3), dpi = 100, legend_cols = 1
80
+ ):
81
+
82
+ import numpy as np
83
+ df = adata.varm[f'{nmf_slot}.{k}']
84
+ nrow = df.shape[0]
85
+ subset = np.random.choice(range(nrow), int(nrow * downsample), replace = False)
86
+ from exprmat.clustering.seriation import pdist
87
+ data = df[subset, :].copy()
88
+ pdistc = pdist(data, metric = metrics)
89
+
90
+ from exprmat.clustering.seriation import serial_matrix, squareform
91
+ serial, order, _ = serial_matrix(squareform(pdistc), method = method)
92
+ indices = adata.var.iloc[subset, :].iloc[order, :].index.tolist()
93
+ if annotations: annotations = adata.var.iloc[subset, :].iloc[order, :][annotations].tolist()
94
+
95
+ return matrix_plot(
96
+ serial, labels = indices, annotations = annotations, cmap_annotations = cmap_annotations,
97
+ cmap = cmap, figsize = figsize, dpi = dpi, show_indices = show_indices, legend_cols = legend_cols
98
+ )
99
+
100
+
101
+ def matrix_plot(
102
+ mat, labels = None, annotations = None,
103
+ cmap = 'Reds_r', cmap_annotations = 'Set1',
104
+ show_indices = True,
105
+ figsize = (3, 3), dpi = 100, legend_cols = 1
106
+ ):
107
+ fig = plt.figure(figsize = figsize, dpi = dpi)
108
+ fig.gca().imshow(mat, cmap = cmap)
109
+ ax = fig.gca()
110
+ ax.set_yticks([])
111
+ ax.set_xticks([])
112
+ if labels is not None and show_indices:
113
+ ax.set_yticks([x for x in range(len(labels))])
114
+ ax.set_yticklabels(labels)
115
+ ax.set_xticks([])
116
+
117
+ if annotations is not None:
118
+ ax_annot = ax.inset_axes([1.02, 0, 0.05, 1], sharey = ax)
119
+ annot_u = list(set(annotations))
120
+ annot_n = [annot_u.index(x) for x in annotations]
121
+
122
+ from exprmat.plotting import palettes
123
+ colors = list(palettes.linear_palette(palettes.all_palettes[cmap_annotations][
124
+ list(palettes.all_palettes[cmap_annotations].keys())[-1]
125
+ ], len(annot_u)))
126
+ colormap = {x: y for x, y in zip(annot_u, colors)}
127
+
128
+ ax_annot.set_xlim(-0.5, 0.5)
129
+ ax_annot.set_ylim(len(annot_n) - 0.5, -0.5)
130
+ for idx, x in enumerate(annot_n):
131
+ ax_annot.fill_between([-0.5, 0.5], [idx - 0.5, idx - 0.5], [idx + 0.5, idx + 0.5], color = colormap[annot_u[x]])
132
+
133
+ # ax_annot.set_yticks([])
134
+ ax_annot.set_xticks([0])
135
+ ax_annot.set_xticklabels([''])
136
+ ax_annot.tick_params(axis = "y", labelleft = False, length = 0)
137
+
138
+ from matplotlib.lines import Line2D as line2d
139
+
140
+ legend_elements = [
141
+ line2d([0], [0], marker = 's', color = 'w', label = alab,
142
+ markerfacecolor = acol, markersize = 8)
143
+ for alab, acol in zip(annot_u, colors)
144
+ ]
145
+
146
+ ax_annot.legend(
147
+ handles = legend_elements,
148
+ bbox_to_anchor = (1.0, 1),
149
+ loc = 'upper left',
150
+ borderaxespad = 0, frameon = False,
151
+ ncol = legend_cols
152
+ )
153
+
154
+ return fig
@@ -58,10 +58,10 @@ def barplot(
58
58
  grid_color = 'lightgray'
59
59
  )
60
60
 
61
- axes.legend().remove()
61
+ axes.legend(bbox_to_anchor = (1.2, 1), loc = 'upper left', borderaxespad = 0, frameon = False)
62
62
  axes.set_xlabel('')
63
63
  axes.set_ylabel(gene)
64
- axes.set_xticks(selected_groups)
64
+ # axes.set_xticks(selected_groups)
65
65
  axes.set_yticks([0.0, 2.5])
66
66
 
67
67
  # axes.set_xticklabels(selected_groups, rotation = 45)
@@ -80,7 +80,7 @@ def barplot(
80
80
  xtl += [ct + '\n{:.3f}'.format(w.pvalue)]
81
81
  else: xtl += [ct]
82
82
 
83
- axes.set_xticks(selected_groups)
83
+ # axes.set_xticks(selected_groups)
84
84
  axes.set_xticklabels(xtl, rotation = 45)
85
85
 
86
86
  else:
@@ -123,6 +123,7 @@ def compare_scatter(
123
123
 
124
124
  plt.xlabel(f'Average expression in {group_x}')
125
125
  plt.ylabel(f'Average expression in {group_y}')
126
+ plt.plot([0, mean_x.max()], [0, mean_x.max()], linewidth = 1, linestyle = '--', color = 'red')
126
127
 
127
128
  for x, y, name in zip(mean_x, mean_y, varn):
128
129
  if name in markers:
@@ -83,7 +83,7 @@ def initialize_tracks(
83
83
  fmtstring = 'Gb'
84
84
 
85
85
  xticklabels = [
86
- str(x * scaler)
86
+ str(x * scaler).replace('.0', '')
87
87
  for x in range(xticksfrom, xticksto + 1)]
88
88
  xticklabels[-1] = xticklabels[-1] + ' ' + fmtstring
89
89
  lastax.set_xticklabels(xticklabels)
@@ -255,8 +255,12 @@ def gene_track(
255
255
  if show_gene_name:
256
256
  ens = gtable['ensembl'].tolist()
257
257
  dname = gtable['gene'].tolist()
258
- if name in ens: displayname = dname[ens.index(name)]
258
+ if name in ens: displayname = dname[ens.index(name)] \
259
+ if str(ens.index(name)) != 'nan' else name
259
260
 
261
+ if displayname == 'nan':
262
+ displayname = ''
263
+
260
264
  ntranscript = len(gene[gene['type'] == 'transcript'])
261
265
  if ntranscript > 1: displayname += f' ({ntranscript})'
262
266
  text = ax.text(max(requested_x, xfrom), requested_y + 0.25, displayname, verticalalignment = 'center')
@@ -435,6 +439,30 @@ def coverage_track_from_bam(
435
439
  return coverage_track(ax, xfrom, xto, xticks, depth[['x', 'y']], color, xlabel, ylabel, show_x_axis)
436
440
 
437
441
 
442
+ def coverage_track_from_bigwig(
443
+ ax, bigwig, xfrom, xto, chrm, xticks, ncpus = 4,
444
+ color = 'blue', xlabel = None, ylabel = None, show_x_axis = True
445
+ ):
446
+ '''
447
+ Examples
448
+ --------
449
+ >>> coverage_track_from_bam(
450
+ >>> axes[3], './fc.bigwig',
451
+ >>> xfrom, xto, chr_bam, xticks, ncpus = 4, xlabel = None, ylabel = 'WT',
452
+ >>> show_x_axis = True
453
+ >>> )
454
+ '''
455
+ import pyBigWig
456
+ from exprmat.ansi import error, warning
457
+ import os
458
+ import pandas
459
+
460
+ bw = pyBigWig.open(bigwig)
461
+ if not bw.chroms(chrm): error(f'specified chromosome {chrm} do not exist in the bigwig file.')
462
+ depth = pandas.DataFrame({'x': [x for x in range(xfrom, xto)], 'y': bw.values(chrm, xfrom, xto)})
463
+ return coverage_track(ax, xfrom, xto, xticks, depth[['x', 'y']], color, xlabel, ylabel, show_x_axis)
464
+
465
+
438
466
  def architecture(assembly, figsize = (4, 8), dpi = 100, cby = 'assembly'):
439
467
  '''
440
468
  Examples
@@ -537,4 +565,26 @@ def genes(
537
565
  from exprmat.ansi import error
538
566
  error('must specify a range or a gene name flanking.')
539
567
  return None
568
+
569
+
570
+ def whereis(assembly, where, upstream = 10000, downstream = 10000):
571
+
572
+ from exprmat.configuration import default as cfg
573
+ from exprmat.data.finders import get_genome
574
+
575
+ gtable = get_genome(cfg['taxa.reference'][assembly.lower()])
576
+ ens = gtable['ensembl'].tolist()
577
+ name = gtable['gene'].tolist()
578
+
579
+ if where in ens:
580
+ geneattr = gtable.iloc[ens.index(where), :].copy()
581
+ elif where in name:
582
+ geneattr = gtable.iloc[name.index(where), :].copy()
583
+ else: geneattr = gtable[where, :].copy()
584
+
585
+ chr = geneattr['.seqid']
586
+ xfrom = geneattr['.start'] - upstream
587
+ xto = geneattr['.end'] + downstream
588
+
589
+ return chr, xfrom, xto
540
590
 
@@ -1,6 +1,7 @@
1
1
 
2
2
  import anndata as ad
3
3
  import numpy as np
4
+ from exprmat.utils import choose_layer
4
5
  from exprmat.ansi import error, warning
5
6
 
6
7
 
@@ -148,6 +149,8 @@ def harmony(
148
149
  *,
149
150
  basis: str = "pca",
150
151
  adjusted_basis: str = "harmony",
152
+ transform_data = False,
153
+ data_slot = 'X',
151
154
  **kwargs,
152
155
  ):
153
156
  """
@@ -220,16 +223,20 @@ def harmony(
220
223
  default_params.update(kwargs)
221
224
  harmony_out = harmonypy.run_harmony(X, adata.obs, key, **default_params)
222
225
  adata.obsm[adjusted_basis] = harmony_out.Z_corr.T
223
- _, x_corr, _, _ = moe_correct_ridge(
224
- X.T, None, None,
225
- harmony_out.R, None,
226
- harmony_out.K, None,
227
- harmony_out.Phi_moe, harmony_out.lamb
228
- )
226
+
227
+ if transform_data:
228
+ data = choose_layer(adata, layer = data_slot)
229
+ _, x_corr, _, _ = moe_correct_ridge(
230
+ data, None, None,
231
+ harmony_out.R, None,
232
+ harmony_out.K, None,
233
+ harmony_out.Phi_moe, harmony_out.lamb
234
+ )
229
235
 
230
- x_corr = np.array(x_corr.T)
231
- x_corr[x_corr < 0] = 0
232
- adata.layers[adjusted_basis] = x_corr
236
+ x_corr = np.array(x_corr.T)
237
+ x_corr[x_corr < 0] = 0
238
+ adata.layers[adjusted_basis] = x_corr
239
+
233
240
  return adata
234
241
 
235
242
 
@@ -71,7 +71,7 @@ class experiment:
71
71
 
72
72
  attempt_path = os.path.join(dump, i_mod, i_sample + '.h5ad')
73
73
  if os.path.exists(attempt_path):
74
- if not i_loc in self.modalities.keys(): self.modalities[i_mod] = {}
74
+ if not i_mod in self.modalities.keys(): self.modalities[i_mod] = {}
75
75
  self.modalities[i_mod][i_sample] = sc.read_h5ad(attempt_path)
76
76
  warning(f'load pre-exisiting file `{i_mod}/{i_sample}.h5ad`.')
77
77
  continue
@@ -534,7 +534,7 @@ class experiment:
534
534
  self, run_on_samples, func,
535
535
  run_on_splits = False, split_key = None, split_selection = None, **kwargs
536
536
  ):
537
- self.plot_for_modality(
537
+ return self.plot_for_modality(
538
538
  'rna', run_on_samples, func,
539
539
  run_on_splits, split_key, split_selection, **kwargs
540
540
  )
@@ -543,7 +543,7 @@ class experiment:
543
543
  self, run_on_samples, func,
544
544
  run_on_splits = False, split_key = None, split_selection = None, **kwargs
545
545
  ):
546
- self.plot_for_modality(
546
+ return self.plot_for_modality(
547
547
  'atac', run_on_samples, func,
548
548
  run_on_splits, split_key, split_selection, **kwargs
549
549
  )
@@ -552,17 +552,16 @@ class experiment:
552
552
  self, run_on_samples, func,
553
553
  run_on_splits = False, split_key = None, split_selection = None, **kwargs
554
554
  ):
555
- self.plot_for_modality(
555
+ return self.plot_for_modality(
556
556
  'atac.cp', run_on_samples, func,
557
557
  run_on_splits, split_key, split_selection, **kwargs
558
558
  )
559
559
 
560
-
561
560
  def plot_for_atac_gene_activity(
562
561
  self, run_on_samples, func,
563
562
  run_on_splits = False, split_key = None, split_selection = None, **kwargs
564
563
  ):
565
- self.plot_for_modality(
564
+ return self.plot_for_modality(
566
565
  'atac.g', run_on_samples, func,
567
566
  run_on_splits, split_key, split_selection, **kwargs
568
567
  )
@@ -12,12 +12,22 @@ class metadata:
12
12
  ----------
13
13
 
14
14
  locations : list[str]
15
- File system paths indicating directories where the 10x-like matrix files locate. The
16
- file reading scheme is default to 10x matrix files including ``matrix.mtx``,
17
- ``barcodes.tsv`` and ``features.tsv``. Appropriate compression levels and column
18
- information is guessed from file extensions and content columns of ``features.tsv``
19
- (or ``genes.tsv``).
15
+ File system paths indicating directories where the data files locate.
16
+ The protocols and procedures on how to load the dump files in the directory is
17
+ determined by `modality` and what this `location` points to. For example,
18
+ when `modality` is `rna`, the program will search for 10X-compatible mtx and
19
+ tsv files if a folder is provided, or h5ad/h5 files if files are specified directly.
20
20
 
21
+ modality : list[str]
22
+ What modality is in the location. Supported values are:
23
+ - `rna` (Single cell RNA-seq),
24
+ - `rna.splicing` (Supplementary spliced/unspliced counts in loom or mtx)
25
+ - `rna.tcr` (10X 5' TCR annotations),
26
+ - `atac` (Single cell ATAC-seq)
27
+
28
+ default_taxa : list[str]
29
+ The reference taxa of the sample.
30
+
21
31
  names : list[str] | None
22
32
  Sample names in the loaded experiment. If left to None, names of the folder will be
23
33
  used. Since the folder names may duplicate, this is not forced to be unique. This might
@@ -28,6 +38,7 @@ class metadata:
28
38
 
29
39
  groups : list[str] | None
30
40
  Experimental groupings, if not set, this column is set to uniform value '.'.
41
+
31
42
 
32
43
  Notes
33
44
  -----------
@@ -37,6 +48,8 @@ class metadata:
37
48
  modality, ``taxa`` for default taxa where no prefix in features is specified. other metadata
38
49
  information is not necessary, and can be appended as specified by user, but do not set duplicate
39
50
  column names as these six.
51
+
52
+ You may load a TSV table as metadata using :py:func:`load_metadata`.
40
53
  """
41
54
 
42
55
  def __init__(
@@ -173,7 +186,7 @@ class metadata:
173
186
 
174
187
  def set_if_ends(self, key = 'sample', dest = 'group', ends = '.', value = '.'):
175
188
  '''
176
- Alter the content of a column if starting with a string in the key column.
189
+ Alter the content of a column if ending with a string in the key column.
177
190
 
178
191
  Parameters
179
192
  ----------
@@ -200,7 +213,7 @@ class metadata:
200
213
 
201
214
  def set_if_contains(self, key = 'sample', dest = 'group', contains = '.', value = '.'):
202
215
  '''
203
- Alter the content of a column if starting with a string in the key column.
216
+ Alter the content of a column if containing a string in the key column.
204
217
 
205
218
  Parameters
206
219
  ----------
@@ -212,7 +225,7 @@ class metadata:
212
225
  The column you may want to alter value according to the patterns in column ``key``,
213
226
  according to the conditions given.
214
227
 
215
- ends : str
228
+ contains : str
216
229
  Test if values is contained in the ``key``. This requires that both variables be string.
217
230
 
218
231
  value : str
@@ -612,9 +612,13 @@ def rna_consensus_nmf(
612
612
  return_k = None, # for the first round, return statistics
613
613
  **kwargs
614
614
  )
615
+
616
+ combs = {}
617
+ for ky in comb.keys():
618
+ combs[str(ky)] = comb[ky]
615
619
 
616
620
  stats = pd.DataFrame(stats, index = ['ncomps', 'threshold', 'silhoutte', 'error']).T
617
- adata.uns[key_added] = comb
621
+ adata.uns[key_added] = combs
618
622
  adata.uns[f'{key_added}.stats'] = stats
619
623
  adata.uns[f'{key_added}.args'] = kwargs
620
624
 
@@ -632,7 +636,10 @@ def rna_consensus_nmf_extract_k(
632
636
  from exprmat.preprocessing import normalize
633
637
 
634
638
  kwargs.update(adata.uns[f'{nmf_slot}.args'])
635
- comb = adata.uns[nmf_slot]
639
+
640
+ comb = {}
641
+ for ky in adata.uns[nmf_slot].keys():
642
+ comb[int(ky)] = adata.uns[nmf_slot][ky]
636
643
 
637
644
  _, res = cnmf(
638
645
  adata, comb = comb,
@@ -641,6 +648,7 @@ def rna_consensus_nmf_extract_k(
641
648
  )
642
649
 
643
650
  local_density, dist, _, rf_usages, spectra_tpm, usage_coef, _ = res
651
+ rf_usages.columns = ['C' + str(x) for x in rf_usages.columns]
644
652
  adata.obsm[usage_added.format(k)] = rf_usages
645
653
  destindex = adata.var_names.tolist()
646
654
 
@@ -1321,6 +1329,11 @@ def rna_plot_cnmf_distance_usages(adata, sample_name, **kwargs):
1321
1329
  return cnmf_distance_usages(adata, **kwargs)
1322
1330
 
1323
1331
 
1332
+ def rna_plot_cnmf_distance_modules(adata, sample_name, **kwargs):
1333
+ from exprmat.plotting.cnmf import cnmf_distance_modules
1334
+ return cnmf_distance_modules(adata, **kwargs)
1335
+
1336
+
1324
1337
  def atac_plot_qc(adata, sample_name, **kwargs):
1325
1338
  from exprmat.plotting.atac import atac_qc_metrics
1326
1339
  return atac_qc_metrics(adata, sample_name, **kwargs)
@@ -368,6 +368,28 @@ seurat_to_10x <- function(srat, outdir) {
368
368
  sparse <- Matrix(srat @ assays $ RNA @ counts, sparse = T)
369
369
  writeMM(sparse, file = paste(outdir, 'matrix.mtx', sep = '/'))
370
370
  }
371
+
372
+ spmatrix_to_mtx <- function(sp, outdir) {
373
+ features <- data.frame(
374
+ ensembl = rownames(sp),
375
+ gene = rownames(sp),
376
+ tag = "Gene Expression"
377
+ )
378
+
379
+ write(
380
+ x = colnames(sp),
381
+ file = paste(outdir, 'barcodes.tsv', sep = '/')
382
+ )
383
+
384
+ write.table(
385
+ x = features,
386
+ file = paste(outdir, 'features.tsv', sep = '/'),
387
+ sep = "\t", quote = FALSE, col.names = FALSE, row.names = FALSE
388
+ )
389
+
390
+ require(Matrix)
391
+ writeMM(sp, file = paste(outdir, 'matrix.mtx', sep = '/'))
392
+ }
371
393
  '''
372
394
 
373
395
 
@@ -18,7 +18,7 @@ description = "exprmat: Routines for expression matrices"
18
18
  readme = "readme.md"
19
19
  license = {file = "license"}
20
20
  requires-python = ">=3.9, <3.13"
21
- version = "0.1.28"
21
+ version = "0.1.30"
22
22
  authors = [
23
23
  {name = "Zheng Yang", email = "xornent@outlook.com"}
24
24
  ]
@@ -80,7 +80,9 @@ dependencies = [
80
80
  'pysam',
81
81
  'hdbscan',
82
82
  'graphtools',
83
- 'bincsync'
83
+ 'bincsync >= 0.3.0',
84
+ 'pyBigWig',
85
+ 'loompy'
84
86
  ]
85
87
 
86
88
  [project.optional-dependencies]