pyadata-cli 0.8.0__tar.gz → 0.10.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/PKG-INFO +4 -3
  2. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/README.md +3 -2
  3. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/pyproject.toml +1 -1
  4. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/cli.py +55 -6
  5. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/conversion/__init__.py +30 -2
  6. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/conversion/base.py +10 -1
  7. pyadata_cli-0.10.0/src/adata/conversion/cellbender.py +657 -0
  8. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/conversion/features.py +10 -4
  9. pyadata_cli-0.10.0/src/adata/conversion/parse.py +404 -0
  10. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/conversion/tenx.py +42 -29
  11. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/core/csr_build.py +50 -1
  12. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/core/subset.py +6 -2
  13. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/elements/write.py +16 -0
  14. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/formats/mtx.py +21 -36
  15. pyadata_cli-0.10.0/src/adata/formats/table.py +364 -0
  16. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/util/names.py +18 -1
  17. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/LICENSE +0 -0
  18. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/__init__.py +0 -0
  19. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/commands/__init__.py +0 -0
  20. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/commands/concat.py +0 -0
  21. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/commands/convert.py +0 -0
  22. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/commands/create.py +0 -0
  23. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/commands/export.py +0 -0
  24. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/commands/import_data.py +0 -0
  25. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/commands/info.py +0 -0
  26. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/commands/ls.py +0 -0
  27. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/commands/recast.py +0 -0
  28. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/commands/split.py +0 -0
  29. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/commands/subset.py +0 -0
  30. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/conversion/anndata_copy.py +0 -0
  31. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/conversion/mtx.py +0 -0
  32. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/core/__init__.py +0 -0
  33. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/core/concat.py +0 -0
  34. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/core/info.py +0 -0
  35. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/core/query.py +0 -0
  36. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/core/read.py +0 -0
  37. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/core/recast.py +0 -0
  38. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/core/select.py +0 -0
  39. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/elements/__init__.py +0 -0
  40. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/elements/read.py +0 -0
  41. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/elements/spec.py +0 -0
  42. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/elements/strings.py +0 -0
  43. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/formats/__init__.py +0 -0
  44. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/formats/array.py +0 -0
  45. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/formats/common.py +0 -0
  46. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/formats/dataframe.py +0 -0
  47. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/formats/image.py +0 -0
  48. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/formats/json_data.py +0 -0
  49. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/formats/sparse.py +0 -0
  50. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/formats/textio.py +0 -0
  51. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/formats/validate.py +0 -0
  52. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/info.py +0 -0
  53. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/py.typed +0 -0
  54. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/read.py +0 -0
  55. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/storage/__init__.py +0 -0
  56. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/util/__init__.py +0 -0
  57. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/util/path.py +0 -0
  58. {pyadata_cli-0.8.0 → pyadata_cli-0.10.0}/src/adata/util/staging.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyadata-cli
3
- Version: 0.8.0
3
+ Version: 0.10.0
4
4
  Summary: Streaming CLI for exploring and editing large AnnData .h5ad and .zarr stores
5
5
  Keywords: anndata,h5ad,zarr,bioinformatics,single-cell,cli
6
6
  Author: Aljes Binkevich
@@ -48,7 +48,7 @@ A command-line tool for exploring huge AnnData stores (`.h5ad` and `.zarr`) with
48
48
  - Auto-detects `.h5ad` files vs `.zarr` directories
49
49
  - Chunked processing for dense and sparse matrices (CSR/CSC)
50
50
  - Reads every AnnData on-disk layout, from 0.7.x through the current spec, and always writes the current one
51
- - Converts between HDF5 and Zarr (v2 and v3) in either direction with `adata convert`, and to and from 10x Genomics HDF5 matrices and 10x / STARsolo MTX folders
51
+ - Converts between HDF5 and Zarr (v2 and v3) in either direction with `adata convert`, and to and from 10x Genomics HDF5 matrices and 10x / STARsolo MTX folders, and from CellBender output
52
52
  - Rich terminal output with progress indicators, kept on stderr so results pipe cleanly
53
53
 
54
54
  **Documentation: [cellgeni.github.io/adata-cli](https://cellgeni.github.io/adata-cli/)**
@@ -96,7 +96,7 @@ Run help at any level (e.g. `adata --help`, `adata export --help`).
96
96
  - `subset` – stream and write a filtered copy, selected by obs/var name lists (`--obs`/`--var`) or by expression (`--obs-query`/`--var-query`).
97
97
  - `split` – write one store per distinct value of an annotation column, with a CSV manifest.
98
98
  - `concat` – concatenate stores along the obs axis, with `--join inner|outer` and merge strategies for var and uns.
99
- - `convert` – change a store's format: h5ad ↔ Zarr v2/v3, 10x Genomics HDF5 (Cell Ranger's `*_feature_bc_matrix.h5`) and 10x / STARsolo MTX folders in and out, streaming, with the output written beside its destination and moved into place only once complete.
99
+ - `convert` – change a store's format: h5ad ↔ Zarr v2/v3, 10x Genomics HDF5 (Cell Ranger's `*_feature_bc_matrix.h5`) and 10x / STARsolo MTX folders in and out, CellBender output in, streaming, with the output written beside its destination and moved into place only once complete.
100
100
  - `recast` – change a matrix's dtype, layout (CSR/CSC/dense) or density, streaming; refuses a lossy cast or a large size increase unless forced. Called `convert` until 0.7.0.
101
101
  - `export` – extract data from a store; subcommands: `dataframe` (any dataframe group to CSV), `array` (dense to `.npy`), `sparse` (CSR/CSC to `.mtx`), `dict` (JSON), `image` (PNG). Results go to stdout when no `--output` is given.
102
102
  - `import` – write new data into a store at any path; subcommands: `dataframe` (CSV), `array` (`.npy`), `sparse` (`.mtx`), `dict` (JSON), `image` (PNG/JPEG/TIFF).
@@ -141,6 +141,7 @@ adata convert data.zarr -o data.h5ad --compression gzip
141
141
  adata convert filtered_feature_bc_matrix.h5 -o counts.h5ad --feature-type "Gene Expression"
142
142
  adata convert counts.h5ad -o for_cellbender.h5 --layer counts
143
143
  adata convert Solo.out/Velocyto/raw -o velocyto.h5ad
144
+ adata convert splitpipe_out -o parse.h5ad --unfiltered
144
145
  ```
145
146
 
146
147
  ## Documentation
@@ -8,7 +8,7 @@ A command-line tool for exploring huge AnnData stores (`.h5ad` and `.zarr`) with
8
8
  - Auto-detects `.h5ad` files vs `.zarr` directories
9
9
  - Chunked processing for dense and sparse matrices (CSR/CSC)
10
10
  - Reads every AnnData on-disk layout, from 0.7.x through the current spec, and always writes the current one
11
- - Converts between HDF5 and Zarr (v2 and v3) in either direction with `adata convert`, and to and from 10x Genomics HDF5 matrices and 10x / STARsolo MTX folders
11
+ - Converts between HDF5 and Zarr (v2 and v3) in either direction with `adata convert`, and to and from 10x Genomics HDF5 matrices and 10x / STARsolo MTX folders, and from CellBender output
12
12
  - Rich terminal output with progress indicators, kept on stderr so results pipe cleanly
13
13
 
14
14
  **Documentation: [cellgeni.github.io/adata-cli](https://cellgeni.github.io/adata-cli/)**
@@ -56,7 +56,7 @@ Run help at any level (e.g. `adata --help`, `adata export --help`).
56
56
  - `subset` – stream and write a filtered copy, selected by obs/var name lists (`--obs`/`--var`) or by expression (`--obs-query`/`--var-query`).
57
57
  - `split` – write one store per distinct value of an annotation column, with a CSV manifest.
58
58
  - `concat` – concatenate stores along the obs axis, with `--join inner|outer` and merge strategies for var and uns.
59
- - `convert` – change a store's format: h5ad ↔ Zarr v2/v3, 10x Genomics HDF5 (Cell Ranger's `*_feature_bc_matrix.h5`) and 10x / STARsolo MTX folders in and out, streaming, with the output written beside its destination and moved into place only once complete.
59
+ - `convert` – change a store's format: h5ad ↔ Zarr v2/v3, 10x Genomics HDF5 (Cell Ranger's `*_feature_bc_matrix.h5`) and 10x / STARsolo MTX folders in and out, CellBender output in, streaming, with the output written beside its destination and moved into place only once complete.
60
60
  - `recast` – change a matrix's dtype, layout (CSR/CSC/dense) or density, streaming; refuses a lossy cast or a large size increase unless forced. Called `convert` until 0.7.0.
61
61
  - `export` – extract data from a store; subcommands: `dataframe` (any dataframe group to CSV), `array` (dense to `.npy`), `sparse` (CSR/CSC to `.mtx`), `dict` (JSON), `image` (PNG). Results go to stdout when no `--output` is given.
62
62
  - `import` – write new data into a store at any path; subcommands: `dataframe` (CSV), `array` (`.npy`), `sparse` (`.mtx`), `dict` (JSON), `image` (PNG/JPEG/TIFF).
@@ -101,6 +101,7 @@ adata convert data.zarr -o data.h5ad --compression gzip
101
101
  adata convert filtered_feature_bc_matrix.h5 -o counts.h5ad --feature-type "Gene Expression"
102
102
  adata convert counts.h5ad -o for_cellbender.h5 --layer counts
103
103
  adata convert Solo.out/Velocyto/raw -o velocyto.h5ad
104
+ adata convert splitpipe_out -o parse.h5ad --unfiltered
104
105
  ```
105
106
 
106
107
  ## Documentation
@@ -3,7 +3,7 @@
3
3
  # so the distribution is published as `pyadata-cli`. The import package
4
4
  # and the command are both still `adata`.
5
5
  name = "pyadata-cli"
6
- version = "0.8.0"
6
+ version = "0.10.0"
7
7
  description = "Streaming CLI for exploring and editing large AnnData .h5ad and .zarr stores"
8
8
  readme = "README.md"
9
9
  requires-python = ">=3.12"
@@ -522,6 +522,11 @@ _CONVERT_FLAGS = {
522
522
  "gene_ids_column": "--gene-ids-column",
523
523
  "gene_names_column": "--gene-names-column",
524
524
  "feature_types_column": "--feature-types-column",
525
+ "raw": "--raw",
526
+ "min_cell_probability": "--min-cell-probability",
527
+ "sample": "--sample",
528
+ "all_samples": "--all-samples",
529
+ "unfiltered": "--unfiltered",
525
530
  }
526
531
 
527
532
  #: Flags that only make sense for format conversion; with recast's flags,
@@ -606,9 +611,10 @@ def convert(
606
611
  "Cell Ranger 2 matrix)",
607
612
  ),
608
613
  var_names: str = typer.Option(
609
- "gene_symbols",
614
+ "gene_ids",
610
615
  "--var-names",
611
- help="10x input: name features by gene_symbols or gene_ids",
616
+ help="10x input: name features by gene_ids (default; unique) or "
617
+ "gene_symbols (scanpy's default)",
612
618
  ),
613
619
  make_unique: bool = typer.Option(
614
620
  False,
@@ -645,6 +651,36 @@ def convert(
645
651
  "--feature-types-column",
646
652
  help="10x output: var column holding feature types (default feature_types)",
647
653
  ),
654
+ raw: Optional[Path] = typer.Option(
655
+ None,
656
+ "--raw",
657
+ help="CellBender input: the raw Cell Ranger .h5 it ran on, added as "
658
+ "layers['cellranger']",
659
+ exists=True,
660
+ dir_okay=False,
661
+ readable=True,
662
+ ),
663
+ min_cell_probability: Optional[float] = typer.Option(
664
+ None,
665
+ "--min-cell-probability",
666
+ help="CellBender input: keep droplets with cell_probability at least "
667
+ "this (CellBender's own cutoff is 0.5)",
668
+ ),
669
+ sample: Optional[str] = typer.Option(
670
+ None,
671
+ "--sample",
672
+ help="Parse input: the sample folder to read (default: all-sample)",
673
+ ),
674
+ all_samples: bool = typer.Option(
675
+ False,
676
+ "--all-samples",
677
+ help="Parse input: write one output per sample, OUT.<sample>.h5ad",
678
+ ),
679
+ unfiltered: bool = typer.Option(
680
+ False,
681
+ "--unfiltered",
682
+ help="Parse input: read DGE_unfiltered (every barcode) not DGE_filtered",
683
+ ),
648
684
  # Deprecated: recast's flags, so `convert` keeps working as it did until
649
685
  # 1.0.0. Hidden from --help; the old matrix paths arrive in ctx.args.
650
686
  inplace: bool = typer.Option(False, "--inplace", hidden=True),
@@ -662,10 +698,14 @@ def convert(
662
698
  Genomics matrix (Cell Ranger's *_feature_bc_matrix.h5); --to 10x-mtx
663
699
  writes a Matrix Market folder. Between h5ad and zarr every element is
664
700
  copied, streamed, keeping the source's chunking and compression where the
665
- target can express them. A 10x matrix is read as scanpy's read_10x_h5 or
666
- read_10x_mtx (gex_only=False) reads it, keeping integer counts, and
667
- written as Cell Ranger writes it. MTX folders from Cell Ranger and
668
- STARsolo, velocyto's included, are read in two streaming passes.
701
+ target can express them. CellBender output keeps its latent variables, as
702
+ CellBender's own loader names them. A 10x matrix is read as scanpy's
703
+ read_10x_h5 or read_10x_mtx (gex_only=False) reads it, keeping integer
704
+ counts, and written as Cell Ranger writes it. MTX folders from Cell
705
+ Ranger and STARsolo, velocyto's included, and Parse split-pipe output
706
+ are read in two streaming passes. Features are named by gene id, unique
707
+ but in probe-level (Flex) matrices; --var-names gene_symbols names them
708
+ as scanpy does.
669
709
 
670
710
  Nothing is written until every check has passed, and the output is moved
671
711
  into place only once complete: a failed conversion leaves nothing
@@ -684,6 +724,10 @@ def convert(
684
724
  adata convert Solo.out/Gene/filtered -o counts.h5ad
685
725
  adata convert Solo.out/Velocyto/raw -o velocyto.h5ad
686
726
  adata convert counts.h5ad -o counts_mtx --to 10x-mtx --layer counts
727
+ adata convert cellbender_output.h5 -o cb.h5ad --raw raw_feature_bc_matrix.h5
728
+ adata convert cellbender_output.h5 -o cells.h5ad --min-cell-probability 0.5
729
+ adata convert splitpipe_out -o parse.h5ad
730
+ adata convert splitpipe_out -o parse.h5ad --all-samples --unfiltered
687
731
  """
688
732
  entries = list(ctx.args)
689
733
  recast_flags = _given(ctx, _RECAST_FLAGS)
@@ -767,6 +811,11 @@ def convert(
767
811
  gene_ids_column=gene_ids_column,
768
812
  gene_names_column=gene_names_column,
769
813
  feature_types_column=feature_types_column,
814
+ raw=raw,
815
+ min_cell_probability=min_cell_probability,
816
+ sample=sample,
817
+ all_samples=all_samples,
818
+ unfiltered=unfiltered,
770
819
  ),
771
820
  )
772
821
  except Exception as e:
@@ -17,7 +17,7 @@ from typing import Dict, FrozenSet, List, Optional
17
17
 
18
18
  import h5py
19
19
 
20
- from adata.conversion import mtx, tenx
20
+ from adata.conversion import cellbender, mtx, parse, tenx
21
21
  from adata.conversion.anndata_copy import AnnDataCopy
22
22
  from adata.conversion.base import ConversionPlan, Converter, Format, Options
23
23
  from adata.storage import has_valid_anndata_root_attrs, is_zarr_path
@@ -66,6 +66,15 @@ FORMATS: Dict[str, Format] = {
66
66
  anndata=True,
67
67
  sniff=is_zarr_path,
68
68
  ),
69
+ # Before 10x-h5: a CellBender file is a 10x matrix too, and the first
70
+ # sniffer to match wins. `--from 10x-h5` still reads one as plain 10x.
71
+ "cellbender": Format(
72
+ name="cellbender",
73
+ description="CellBender remove-background output (0.2 and later)",
74
+ extensions=(".h5",),
75
+ sniff=cellbender.sniff,
76
+ importer=cellbender.CellbenderImport(),
77
+ ),
69
78
  "10x-h5": Format(
70
79
  name="10x-h5",
71
80
  description="10x Genomics feature-barcode matrix (Cell Ranger v2 or v3)",
@@ -83,6 +92,14 @@ FORMATS: Dict[str, Format] = {
83
92
  importer=mtx.MtxImport(),
84
93
  exporter=mtx.MtxExport(),
85
94
  ),
95
+ # A folder too; read only.
96
+ "parse": Format(
97
+ name="parse",
98
+ description="Parse Biosciences split-pipe output (a run, sample or DGE folder)",
99
+ extensions=(),
100
+ sniff=parse.sniff,
101
+ importer=parse.ParseImport(),
102
+ ),
86
103
  }
87
104
 
88
105
  _ANNDATA_COPY = AnnDataCopy()
@@ -136,10 +153,21 @@ def output_format(path: Path, requested: Optional[str] = None) -> str:
136
153
  path = Path(path)
137
154
  if requested is not None and requested not in FORMATS:
138
155
  raise ValueError(f"Unknown format {requested!r}; use one of: {_names()}.")
156
+ if requested is not None and not (
157
+ FORMATS[requested].anndata or FORMATS[requested].exporter is not None
158
+ ):
159
+ raise ValueError(f"{requested} can be read but not written.")
139
160
 
140
161
  suffix = path.suffix.lower()
162
+ # Only formats that can be written: `.h5` names CellBender output too,
163
+ # but an `.h5` output is a 10x matrix.
141
164
  by_extension = next(
142
- (fmt.name for fmt in FORMATS.values() if suffix in fmt.extensions), None
165
+ (
166
+ fmt.name
167
+ for fmt in FORMATS.values()
168
+ if suffix in fmt.extensions and (fmt.anndata or fmt.exporter is not None)
169
+ ),
170
+ None,
143
171
  )
144
172
  if requested is None:
145
173
  if by_extension is None:
@@ -24,7 +24,7 @@ class Options:
24
24
 
25
25
  # Reading a 10x matrix.
26
26
  genome: Optional[str] = None
27
- var_names: str = "gene_symbols"
27
+ var_names: str = "gene_ids"
28
28
  make_unique: bool = False
29
29
  feature_type: Optional[str] = None
30
30
  split_feature_types: bool = False
@@ -35,6 +35,15 @@ class Options:
35
35
  gene_names_column: Optional[str] = None
36
36
  feature_types_column: Optional[str] = None
37
37
 
38
+ # Reading CellBender output.
39
+ raw: Optional[Path] = None
40
+ min_cell_probability: Optional[float] = None
41
+
42
+ # Reading Parse split-pipe output.
43
+ sample: Optional[str] = None
44
+ all_samples: bool = False
45
+ unfiltered: bool = False
46
+
38
47
 
39
48
  @dataclass
40
49
  class ConversionPlan: