Skip to content

Commit

Permalink
refactor: change type hints to PEP585
Browse files Browse the repository at this point in the history
  • Loading branch information
BorisMuzellec committed Dec 12, 2024
1 parent 46b7084 commit 1e36fbe
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 94 deletions.
31 changes: 13 additions & 18 deletions pydeseq2/dds.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import sys
import time
import warnings
from typing import List
from typing import Literal
from typing import Optional
from typing import Union
from typing import cast

import anndata as ad # type: ignore
Expand Down Expand Up @@ -202,9 +199,9 @@ class DeseqDataSet(ad.AnnData):
def __init__(
self,
*,
adata: Optional[ad.AnnData] = None,
counts: Optional[pd.DataFrame] = None,
metadata: Optional[pd.DataFrame] = None,
adata: ad.AnnData | None = None,
counts: pd.DataFrame | None = None,
metadata: pd.DataFrame | None = None,
design: str | pd.DataFrame = "~condition",
design_factors: str | list[str] | None = None,
continuous_factors: list[str] | None = None,
Expand All @@ -217,8 +214,8 @@ def __init__(
refit_cooks: bool = True,
min_replicates: int = 7,
beta_tol: float = 1e-8,
n_cpus: Optional[int] = None,
inference: Optional[Inference] = None,
n_cpus: int | None = None,
inference: Inference | None = None,
quiet: bool = False,
low_memory: bool = False,
) -> None:
Expand Down Expand Up @@ -342,7 +339,7 @@ def variables(self):
def vst(
self,
use_design: bool = False,
fit_type: Optional[Literal["parametric", "mean"]] = None,
fit_type: Literal["parametric", "mean"] | None = None,
) -> None:
"""Fit a variance stabilizing transformation, and apply it to normalized counts.
Expand Down Expand Up @@ -427,7 +424,7 @@ def vst_fit(
self.obsm["design_matrix"] = self.obsm["design_matrix_buffer"].copy()
del self.obsm["design_matrix_buffer"]

def vst_transform(self, counts: Optional[np.ndarray] = None) -> np.ndarray:
def vst_transform(self, counts: np.ndarray | None = None) -> np.ndarray:
"""Apply the variance stabilizing transformation.
Uses the results from the ``vst_fit`` method.
Expand Down Expand Up @@ -501,7 +498,7 @@ def vst_transform(self, counts: Optional[np.ndarray] = None) -> np.ndarray:
f"Found fit_type '{self.vst_fit_type}'. Expected 'parametric' or 'mean'."
)

def deseq2(self, fit_type: Optional[Literal["parametric", "mean"]] = None) -> None:
def deseq2(self, fit_type: Literal["parametric", "mean"] | None = None) -> None:
"""Perform dispersion and log fold-change (LFC) estimation.
Wrapper for the first part of the PyDESeq2 pipeline.
Expand Down Expand Up @@ -568,10 +565,8 @@ def contrast(self, *args, **kwargs):

def fit_size_factors(
self,
fit_type: Optional[Literal["ratio", "poscounts", "iterative"]] = None,
control_genes: Optional[
Union[np.ndarray, List[str], List[int], pd.Index]
] = None,
fit_type: Literal["ratio", "poscounts", "iterative"] | None = None,
control_genes: np.ndarray | list[str] | list[int] | pd.Index | None = None,
) -> None:
"""Fit sample-wise deseq2 normalization (size) factors.
Expand Down Expand Up @@ -599,7 +594,7 @@ def fit_size_factors(
fit_type : str
The normalization method to use: "ratio", "poscounts" or "iterative".
(default: ``"ratio"``).
control_genes : ndarray, list, pandas.Index, or None
control_genes : ndarray, list, or pandas.Index, optional
Genes to use as control genes for size factor fitting. If None, all genes
are used. (default: ``None``).
"""
Expand Down Expand Up @@ -1127,7 +1122,7 @@ def _fit_MoM_dispersions(self) -> None:
)

def plot_dispersions(
self, log: bool = True, save_path: Optional[str] = None, **kwargs
self, log: bool = True, save_path: str | None = None, **kwargs
) -> None:
"""Plot dispersions.
Expand All @@ -1139,7 +1134,7 @@ def plot_dispersions(
log : bool
Whether to log scale x and y axes (``default=True``).
save_path : str or None
save_path : str, optional
The path where to save the plot. If left None, the plot won't be saved
(``default=None``).
Expand Down
22 changes: 10 additions & 12 deletions pydeseq2/default_inference.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
from typing import Literal
from typing import Optional
from typing import Tuple

import numpy as np
import pandas as pd
Expand Down Expand Up @@ -41,7 +39,7 @@ def __init__(
self,
joblib_verbosity: int = 0,
batch_size: int = 128,
n_cpus: Optional[int] = None,
n_cpus: int | None = None,
backend: str = "loky",
):
self._joblib_verbosity = joblib_verbosity
Expand Down Expand Up @@ -94,7 +92,7 @@ def irls( # noqa: D102
max_beta: float = 30,
optimizer: Literal["BFGS", "L-BFGS-B"] = "L-BFGS-B",
maxiter: int = 250,
) -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]:
) -> tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]:
with parallel_backend(self._backend, inner_max_num_threads=1):
res = Parallel(
n_jobs=self.n_cpus,
Expand Down Expand Up @@ -133,11 +131,11 @@ def alpha_mle( # noqa: D102
alpha_hat: np.ndarray,
min_disp: float,
max_disp: float,
prior_disp_var: Optional[float] = None,
prior_disp_var: float | None = None,
cr_reg: bool = True,
prior_reg: bool = False,
optimizer: Literal["BFGS", "L-BFGS-B"] = "L-BFGS-B",
) -> Tuple[np.ndarray, np.ndarray]:
) -> tuple[np.ndarray, np.ndarray]:
with parallel_backend(self._backend, inner_max_num_threads=1):
res = Parallel(
n_jobs=self.n_cpus,
Expand Down Expand Up @@ -171,10 +169,10 @@ def wald_test( # noqa: D102
ridge_factor: np.ndarray,
contrast: np.ndarray,
lfc_null: np.ndarray,
alt_hypothesis: Optional[
Literal["greaterAbs", "lessAbs", "greater", "less"]
] = None,
) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
alt_hypothesis: (
Literal["greaterAbs", "lessAbs", "greater", "less"] | None
) = None,
) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
num_genes = mu.shape[1]
with parallel_backend(self._backend, inner_max_num_threads=1):
res = Parallel(
Expand All @@ -201,7 +199,7 @@ def wald_test( # noqa: D102

def dispersion_trend_gamma_glm( # noqa: D102
self, covariates: pd.Series, targets: pd.Series
) -> Tuple[np.ndarray, np.ndarray, bool]:
) -> tuple[np.ndarray, np.ndarray, bool]:
covariates_w_intercept = covariates.to_frame()
covariates_w_intercept.insert(0, "intercept", 1)
covariates_fit = covariates_w_intercept.values
Expand Down Expand Up @@ -241,7 +239,7 @@ def lfc_shrink_nbinom_glm( # noqa: D102
prior_scale: float,
optimizer: str,
shrink_index: int,
) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
with parallel_backend(self._backend, inner_max_num_threads=1):
num_genes = counts.shape[1]
res = Parallel(
Expand Down
22 changes: 10 additions & 12 deletions pydeseq2/ds.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import sys
import time
from typing import List
from typing import Literal
from typing import Optional

# import anndata as ad
import numpy as np
Expand Down Expand Up @@ -57,7 +55,7 @@ class DeseqStats:
lfc_null : float
The (log2) log fold change under the null hypothesis. (default: ``0``).
alt_hypothesis : str or None
alt_hypothesis : str, optional
The alternative hypothesis for computing wald p-values. By default, the normal
Wald test assesses deviation of the estimated log fold change from the null
hypothesis, as given by ``lfc_null``.
Expand All @@ -81,7 +79,7 @@ class DeseqStats:
lfc_null : float
The (log2) log fold change under the null hypothesis.
alt_hypothesis : str or None
alt_hypothesis : str, optional
The alternative hypothesis for computing wald p-values.
contrast_vector : ndarray
Expand Down Expand Up @@ -132,16 +130,16 @@ class DeseqStats:
def __init__(
self,
dds: DeseqDataSet,
contrast: List[str] | np.ndarray,
contrast: list[str] | np.ndarray,
alpha: float = 0.05,
cooks_filter: bool = True,
independent_filter: bool = True,
prior_LFC_var: Optional[np.ndarray] = None,
prior_LFC_var: np.ndarray | None = None,
lfc_null: float = 0.0,
alt_hypothesis: Optional[
Literal["greaterAbs", "lessAbs", "greater", "less"]
] = None,
inference: Optional[Inference] = None,
alt_hypothesis: (
Literal["greaterAbs", "lessAbs", "greater", "less"] | None
) = None,
inference: Inference | None = None,
quiet: bool = False,
) -> None:
assert (
Expand Down Expand Up @@ -436,7 +434,7 @@ def lfc_shrink(self, coeff: str, adapt: bool = True) -> None:
if not self.quiet:
print(self.results_df)

def plot_MA(self, log: bool = True, save_path: Optional[str] = None, **kwargs):
def plot_MA(self, log: bool = True, save_path: str | None = None, **kwargs):
"""
Create an log ratio (M)-average (A) plot using matplotlib.
Expand All @@ -449,7 +447,7 @@ def plot_MA(self, log: bool = True, save_path: Optional[str] = None, **kwargs):
log : bool
Whether or not to log scale x and y axes (``default=True``).
save_path : str or None
save_path : str, optional
The path where to save the plot. If left None, the plot won't be saved
(``default=None``).
Expand Down
6 changes: 2 additions & 4 deletions pydeseq2/grid_search.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from typing import Optional

import numpy as np
from scipy.special import gammaln # type: ignore

Expand Down Expand Up @@ -58,7 +56,7 @@ def grid_fit_alpha(
alpha_hat: float,
min_disp: float,
max_disp: float,
prior_disp_var: Optional[float] = None,
prior_disp_var: float | None = None,
cr_reg: bool = True,
prior_reg: bool = False,
grid_length: int = 100,
Expand Down Expand Up @@ -87,7 +85,7 @@ def grid_fit_alpha(
max_disp : float
Upper threshold for dispersion parameters.
prior_disp_var : float
prior_disp_var : float, optional
Prior dispersion variance.
cr_reg : bool
Expand Down
22 changes: 10 additions & 12 deletions pydeseq2/inference.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
from abc import ABC
from abc import abstractmethod
from typing import Literal
from typing import Optional
from typing import Tuple

import numpy as np
import pandas as pd
Expand Down Expand Up @@ -57,7 +55,7 @@ def irls(
max_beta: float = 30,
optimizer: Literal["BFGS", "L-BFGS-B"] = "L-BFGS-B",
maxiter: int = 250,
) -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]:
) -> tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]:
r"""Fit a NB GLM wit log-link to predict counts from the design matrix.
See equations (1-2) in the DESeq2 paper.
Expand Down Expand Up @@ -128,11 +126,11 @@ def alpha_mle(
alpha_hat: np.ndarray,
min_disp: float,
max_disp: float,
prior_disp_var: Optional[float] = None,
prior_disp_var: float | None = None,
cr_reg: bool = True,
prior_reg: bool = False,
optimizer: Literal["BFGS", "L-BFGS-B"] = "L-BFGS-B",
) -> Tuple[np.ndarray, np.ndarray]:
) -> tuple[np.ndarray, np.ndarray]:
"""Estimate the dispersion parameter of a negative binomial GLM.
Parameters
Expand All @@ -155,7 +153,7 @@ def alpha_mle(
max_disp : float
Upper threshold for dispersion parameters.
prior_disp_var : float
prior_disp_var : float, optional
Prior dispersion variance.
cr_reg : bool
Expand Down Expand Up @@ -188,10 +186,10 @@ def wald_test(
ridge_factor: np.ndarray,
contrast: np.ndarray,
lfc_null: np.ndarray,
alt_hypothesis: Optional[
Literal["greaterAbs", "lessAbs", "greater", "less"]
] = None,
) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
alt_hypothesis: (
Literal["greaterAbs", "lessAbs", "greater", "less"] | None
) = None,
) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
"""Run Wald test for differential expression.
Computes Wald statistics, standard error and p-values from
Expand Down Expand Up @@ -285,7 +283,7 @@ def fit_moments_dispersions(
@abstractmethod
def dispersion_trend_gamma_glm(
self, covariates: pd.Series, targets: pd.Series
) -> Tuple[np.ndarray, np.ndarray, bool]:
) -> tuple[np.ndarray, np.ndarray, bool]:
"""Fit a gamma glm on gene dispersions.
The intercept should be concatenated in this method
Expand Down Expand Up @@ -319,7 +317,7 @@ def lfc_shrink_nbinom_glm(
prior_scale: float,
optimizer: str,
shrink_index: int,
) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
"""Fit a negative binomial MAP LFC using an apeGLM prior.
Only the LFC is shrinked, and not the intercept.
Expand Down
15 changes: 5 additions & 10 deletions pydeseq2/preprocessing.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
from typing import Tuple
from typing import Union

import numpy as np
import pandas as pd


def deseq2_norm(
counts: Union[pd.DataFrame, np.ndarray]
) -> Tuple[Union[pd.DataFrame, np.ndarray], Union[pd.DataFrame, np.ndarray]]:
counts: pd.DataFrame | np.ndarray,
) -> tuple[pd.DataFrame | np.ndarray, pd.DataFrame | np.ndarray]:
"""Return normalized counts and size_factors.
Uses the median of ratios method.
Expand All @@ -31,9 +28,7 @@ def deseq2_norm(
return deseq2_counts, size_factors


def deseq2_norm_fit(
counts: Union[pd.DataFrame, np.ndarray]
) -> Tuple[np.ndarray, np.ndarray]:
def deseq2_norm_fit(counts: pd.DataFrame | np.ndarray) -> tuple[np.ndarray, np.ndarray]:
"""Return ``logmeans`` and ``filtered_genes``, needed in the median of ratios method.
``Logmeans`` and ``filtered_genes`` can then be used to normalize external datasets.
Expand Down Expand Up @@ -62,10 +57,10 @@ def deseq2_norm_fit(


def deseq2_norm_transform(
counts: Union[pd.DataFrame, np.ndarray],
counts: pd.DataFrame | np.ndarray,
logmeans: np.ndarray,
filtered_genes: np.ndarray,
) -> Tuple[Union[pd.DataFrame, np.ndarray], Union[pd.DataFrame, np.ndarray]]:
) -> tuple[pd.DataFrame | np.ndarray, pd.DataFrame | np.ndarray]:
"""Return normalized counts and size factors from the median of ratios method.
Can be applied on external dataset, using the ``logmeans`` and ``filtered_genes``
Expand Down
Loading

0 comments on commit 1e36fbe

Please sign in to comment.