Skip to content

Commit

Permalink
Scrublet (#129)
Browse files Browse the repository at this point in the history
* copy over scrublet from scanpy

* update normalize and log1p

* update scrublet

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* updated log1p

* updates verbose for filters

* first working implementation for scrublet

* add tests

* update to working

* use cusparse for dense

* added docs

* update docstring

* added release notes

* updates docs

* fixes docstring

* fixes docs

* updates releasenotes

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
Intron7 and pre-commit-ci[bot] committed Mar 6, 2024
1 parent dfa069d commit a64af42
Show file tree
Hide file tree
Showing 10 changed files with 1,486 additions and 17 deletions.
10 changes: 10 additions & 0 deletions docs/api/scanpy_gpu.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,16 @@ Any transformation of the data matrix that is not a tool. Other than `tools`, pr
pp.harmony_integrate
```

### Doublet detection
```{eval-rst}
.. autosummary::
:toctree: generated/
pp.scrublet
pp.scrublet_simulate_doublets
```


### Neighbors
```{eval-rst}
.. autosummary::
Expand Down
5 changes: 5 additions & 0 deletions docs/release-notes/0.10.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
* added `get` module {pr}`100` {smaller}`S Dicks`
* switch `utils` functions to get {pr}`100` {smaller}`S Dicks`
* added `get.aggregated` to create condensed `anndata` objects {pr}`100` {smaller}`S Dicks`
* added `pp.scrublet` and `pp.scrublet_simulate_doublets` {pr}`129` {smaller}`S Dicks`

```{rubric} Bug fixes
```
* Fixes an issue where `pp.normalize` and `pp.log1p` now use `copy` and `inplace` corretly {pr}`129` {smaller}`S Dicks`

```{rubric} Removals
```
Expand Down
1 change: 1 addition & 0 deletions src/rapids_singlecell/preprocessing/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from ._pca import pca
from ._regress_out import regress_out
from ._scale import scale
from ._scrublet import scrublet, scrublet_simulate_doublets
from ._simple import (
calculate_qc_metrics,
filter_cells,
Expand Down
55 changes: 44 additions & 11 deletions src/rapids_singlecell/preprocessing/_normalize.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@

def normalize_total(
adata: AnnData,
*,
target_sum: Optional[int] = None,
layer: Optional[str] = None,
inplace: bool = True,
) -> Optional[Union[sparse.csr_matrix, cp.ndarray]]:
copy: bool = False,
) -> Optional[Union[AnnData, sparse.csr_matrix, cp.ndarray]]:
"""
Normalizes rows in matrix so they sum to `target_sum`
Expand All @@ -31,15 +33,21 @@ def normalize_total(
Layer to normalize instead of `X`. If `None`, `X` is normalized.
inplace
Whether to update `adata` or return the normalized matrix.
Whether to update `adata` or return the matrix.
copy
Whether to return a copy or update `adata`. Not compatible with inplace=False.
Returns
-------
Returns a normalized copy or updates `adata` with a normalized version of \
the original `adata.X` and `adata.layers['layer']`, depending on `inplace`.
"""
if copy:
if not inplace:
raise ValueError("`copy=True` cannot be used with `inplace=False`.")
adata = adata.copy()
X = _get_obs_rep(adata, layer=layer)

_check_gpu_X(X)
Expand Down Expand Up @@ -88,13 +96,21 @@ def normalize_total(

if inplace:
_set_obs_rep(adata, X, layer=layer)
else:

if copy:
return adata
elif not inplace:
return X


def log1p(
adata: AnnData, layer: Optional[str] = None, copy: bool = False
) -> Optional[Union[sparse.csr_matrix, cp.ndarray]]:
adata: AnnData,
*,
layer: Optional[str] = None,
obsm: Optional[str] = None,
inplace: bool = True,
copy: bool = False,
) -> Optional[Union[AnnData, sparse.csr_matrix, cp.ndarray]]:
"""
Calculated the natural logarithm of one plus the sparse matrix.
Expand All @@ -106,8 +122,14 @@ def log1p(
layer
Layer to normalize instead of `X`. If `None`, `X` is normalized.
obsm
Entry of obsm to transform.
inplace
Whether to update `adata` or return the matrix.
copy
Whether to return a copy or update `adata`.
Whether to return a copy or update `adata`. Not compatible with inplace=False.
Returns
-------
Expand All @@ -116,15 +138,26 @@ def log1p(
in-place and returns None.
"""
X = _get_obs_rep(adata, layer=layer)
if copy:
if not inplace:
raise ValueError("`copy=True` cannot be used with `inplace=False`.")
adata = adata.copy()
X = _get_obs_rep(adata, layer=layer, obsm=obsm)

_check_gpu_X(X)

X = X.log1p()
adata.uns["log1p"] = {"base": None}
if not copy:
_set_obs_rep(adata, X, layer=layer)
if isinstance(X, cp.ndarray):
X = cp.log1p(X)
else:
X = X.log1p()

adata.uns["log1p"] = {"base": None}
if inplace:
_set_obs_rep(adata, X, layer=layer, obsm=obsm)

if copy:
return adata
elif not inplace:
return X


Expand Down

0 comments on commit a64af42

Please sign in to comment.