|
3 | 3 | Notable changes to `adata-cli`. Versions are `MAJOR.MINOR.PATCH`; tags carry no |
4 | 4 | `v` prefix. |
5 | 5 |
|
| 6 | +## 0.8.0 |
| 7 | + |
| 8 | +Adds 10x Genomics and STARsolo Matrix Market folders to `adata convert`, in |
| 9 | +both directions, velocyto's included. They are read in two streaming passes, |
| 10 | +so a folder's size is not a limit. `import sparse` and `export sparse` move |
| 11 | +onto the same reader and writer, which changes what `import sparse` writes |
| 12 | +and fixes a symmetric file being read as half its matrix. |
| 13 | + |
| 14 | +### Added |
| 15 | + |
| 16 | +- **`adata convert` reads 10x and STARsolo MTX folders** |
| 17 | + ([#24](https://github.com/cellgeni/adata-cli/issues/24)). A folder |
| 18 | + holding `matrix.mtx`, `barcodes.tsv` and `features.tsv` (or Cell Ranger |
| 19 | + 2's `genes.tsv`), each plain or gzipped, is recognised whatever its name: |
| 20 | + - Cell Ranger 3 and later; |
| 21 | + - Cell Ranger 2, with one subfolder per genome, picked with `--genome`; |
| 22 | + - STARsolo `Gene/`, `GeneFull/` and the like; |
| 23 | + - STARsolo `Velocyto/raw/`, whose `spliced`, `unspliced` and `ambiguous` |
| 24 | + matrices become layers of those names, with X a copy of `spliced`; |
| 25 | + - any of these with every file under one GEO-style prefix |
| 26 | + (`GSM123_matrix.mtx.gz`). |
| 27 | + |
| 28 | + The result matches `scanpy.read_10x_mtx(gex_only=False)` column for |
| 29 | + column, checked against scanpy in CI, except that integer counts stay |
| 30 | + integers. The 10x HDF5 flags apply (`--genome`, `--var-names`, |
| 31 | + `--make-unique`, `--feature-type`, `--split-feature-types`), as does |
| 32 | + `--compression`. The first pass checks the whole folder before any output |
| 33 | + exists; the second writes X, straight through when entries are in barcode |
| 34 | + order, as Cell Ranger and STARsolo write them, and through on-disk buckets |
| 35 | + when they are not. On 50 million entries this took the time scanpy did, at |
| 36 | + under a fifth of its peak memory, and the peak did not grow with the input. |
| 37 | + |
| 38 | +- **`adata convert --to 10x-mtx` writes a Cell Ranger 3 folder** |
| 39 | + ([#24](https://github.com/cellgeni/adata-cli/issues/24)): gzipped (or not, |
| 40 | + with `--compression none`), three feature columns, entries in barcode |
| 41 | + order, from X or the matrix `--layer` names. Feature ids and types come |
| 42 | + from var as for the 10x HDF5 export. A folder imported by `convert` |
| 43 | + exports with Cell Ranger's `%metadata_json` intact. |
| 44 | + |
| 45 | +- **A benchmark case for MTX import** ([#49](https://github.com/cellgeni/adata-cli/pull/49)), against scanpy's |
| 46 | + `read_10x_mtx`. |
| 47 | + |
| 48 | +### Changed |
| 49 | + |
| 50 | +- **`import sparse` keeps integer values as integers** |
| 51 | + ([#24](https://github.com/cellgeni/adata-cli/issues/24)). An `integer` |
| 52 | + Matrix Market file becomes int32, or int64 when a value needs it; a `real` |
| 53 | + one becomes float64; a `pattern` one becomes int32 ones. All three were |
| 54 | + float32, which cannot hold counts above 2^24 exactly. `adata recast |
| 55 | + --dtype float32` narrows on request. Duplicate entries are now summed, as |
| 56 | + scipy does, and reported. The data is gzipped in an h5ad, and a parent |
| 57 | + group made on the way (`layers`) is a proper dict. |
| 58 | + |
| 59 | +- **`import sparse` and `export sparse` stream** ([#48](https://github.com/cellgeni/adata-cli/pull/48)), and read or |
| 60 | + write gzipped files (`.mtx.gz`). Import makes two passes and checks the whole file |
| 61 | + before the store is touched; it used to build a Python object per entry. |
| 62 | + Export reads `indices` and `data` once per block, where it read both once |
| 63 | + per row, and writes floats with the digits to read back exactly and whole |
| 64 | + numbers as integers. |
| 65 | + |
| 66 | +### Fixed |
| 67 | + |
| 68 | +- **A `symmetric` Matrix Market file was read as half its matrix** |
| 69 | + ([#48](https://github.com/cellgeni/adata-cli/pull/48)). It |
| 70 | + stores one triangle and means both, and `import sparse` read it as |
| 71 | + `general`. `symmetric`, `skew-symmetric`, `hermitian`, `complex` and dense |
| 72 | + `array` files are now refused by name. |
| 73 | + |
| 74 | +- **`import sparse` overflowed `indptr` past 2^31 entries** ([#48](https://github.com/cellgeni/adata-cli/pull/48)); it |
| 75 | + widens to int64 when needed. |
| 76 | + |
| 77 | +- **`recast --layout` spent time in proportion to the matrix on every |
| 78 | + block** of a streaming transpose ([#47](https://github.com/cellgeni/adata-cli/pull/47)): pass 1 counted over every output row per |
| 79 | + block, and pass 2 compared each block against every bucket. Both now cost |
| 80 | + what the block costs. |
| 81 | + |
6 | 82 | ## 0.7.1 |
7 | 83 |
|
8 | 84 | Fixes ways that `subset`, `recast`, `split` and `concat` could lose or |
|
0 commit comments