Skip to content

Commit

Permalink
Merge pull request aristoteleo#690 from chansigit/master
Browse files Browse the repository at this point in the history
init a branch for fixing
  • Loading branch information
chansigit authored Jul 8, 2024
2 parents a5a1998 + 3339f3d commit 7e464dc
Show file tree
Hide file tree
Showing 107 changed files with 1,292 additions and 880 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/python-docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-lastest, windows-2016]
node-version: [12.x, 14.x]
node-version: [22.x, 24.x]

steps:
- uses: actions/checkout@v1
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.7, 3.8, 3.9]
python-version: [3.8, 3.9, 3.10.14, 3.11]

steps:
- uses: actions/checkout@v2
Expand All @@ -40,4 +40,4 @@ jobs:
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
# - name: Test with pytest
# run: |
# pytest
# pytest
3 changes: 2 additions & 1 deletion .github/workflows/python-plain-run-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.8, 3.9]
python-version: [3.8, 3.9, 3.10.14, 3.11]

continue-on-error: true
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
Expand Down
23 changes: 14 additions & 9 deletions docs/source/_ext/pdfembed.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from docutils import nodes


def pdfembed_html(pdfembed_specs):
"""
Build the iframe code for the pdf file,
Expand All @@ -20,27 +21,31 @@ def pdfembed_html(pdfembed_specs):
align="%s">
</iframe>
"""
return ( html_base_code % (pdfembed_specs['src' ],
pdfembed_specs['height'],
pdfembed_specs['width' ],
pdfembed_specs['align' ]) )
return html_base_code % (
pdfembed_specs["src"],
pdfembed_specs["height"],
pdfembed_specs["width"],
pdfembed_specs["align"],
)


def pdfembed_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
"""
Get iframe specifications and generate the associate HTML code for the pdf iframe.
"""
# parse and init variables
text = text.replace(' ', '')
text = text.replace(" ", "")
pdfembed_specs = {}
# read specs
for component in text.split(','):
pdfembed_specs[component.split(':')[0]] = component.split(':')[1]
for component in text.split(","):
pdfembed_specs[component.split(":")[0]] = component.split(":")[1]
# build node from pdf iframe html code
node = nodes.raw('', pdfembed_html(pdfembed_specs), format='html')
node = nodes.raw("", pdfembed_html(pdfembed_specs), format="html")
return [node], []


def setup(app):
"""
Set up the app with the extension function
"""
app.add_role('pdfembed', pdfembed_role)
app.add_role("pdfembed", pdfembed_role)
2 changes: 1 addition & 1 deletion docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@
"sphinxcontrib.bibtex",
"sphinx_gallery.load_style",
# pdf embed
'pdfembed',
"pdfembed",
]

# Mappings for sphinx.ext.intersphinx. Projects have to have Sphinx-generated doc! (.inv file)
Expand Down
3 changes: 1 addition & 2 deletions dynamo/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Mapping Vector Field of Single Cells
"""

from .get_version import get_version, get_dynamo_version
from .get_version import get_dynamo_version, get_version

__version__ = get_version(__file__)
del get_version
Expand All @@ -19,7 +19,6 @@
from . import mv
from . import shiny
from . import sim
from .data_io import *
from . import sample_data
from . import configuration
from . import ext
Expand Down
74 changes: 43 additions & 31 deletions dynamo/configuration.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import warnings
from typing import Any, List, Generator, Optional, Tuple, Union
from typing import Any, Generator, List, Optional, Tuple, Union

import colorcet
import matplotlib
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
Expand All @@ -15,6 +16,7 @@

class DynamoAdataKeyManager:
"""A class to manage the keys used in anndata object for dynamo."""

VAR_GENE_MEAN_KEY = "pp_gene_mean"
VAR_GENE_VAR_KEY = "pp_gene_variance"
VAR_GENE_HIGHLY_VARIABLE_KEY = "gene_highly_variable"
Expand All @@ -41,8 +43,8 @@ class DynamoAdataKeyManager:
RAW = "raw"

def _select_layer_cell_chunked_data(
mat: np.ndarray,
chunk_size: int,
mat: np.ndarray,
chunk_size: int,
) -> Generator:
"""Select layer data in cell chunks based on chunk_size."""
start = 0
Expand All @@ -55,8 +57,8 @@ def _select_layer_cell_chunked_data(
yield (mat[start:n, :], start, n)

def _select_layer_gene_chunked_data(
mat: np.ndarray,
chunk_size: int,
mat: np.ndarray,
chunk_size: int,
) -> Generator:
"""Select layer data in gene chunks based on chunk_size."""
start = 0
Expand Down Expand Up @@ -131,8 +133,11 @@ def select_layer_chunked_data(
elif layer == DynamoAdataKeyManager.RAW:
return DynamoAdataKeyManager._select_layer_cell_chunked_data(adata.raw.X, chunk_size=chunk_size)
elif layer == DynamoAdataKeyManager.PROTEIN_LAYER:
return DynamoAdataKeyManager._select_layer_cell_chunked_data(
adata.obsm["protein"], chunk_size=chunk_size) if "protein" in adata.obsm_keys() else None
return (
DynamoAdataKeyManager._select_layer_cell_chunked_data(adata.obsm["protein"], chunk_size=chunk_size)
if "protein" in adata.obsm_keys()
else None
)
else:
return DynamoAdataKeyManager._select_layer_cell_chunked_data(adata.layers[layer], chunk_size=chunk_size)
elif chunk_mode == "gene":
Expand All @@ -141,8 +146,11 @@ def select_layer_chunked_data(
elif layer == DynamoAdataKeyManager.RAW:
return DynamoAdataKeyManager._select_layer_gene_chunked_data(adata.raw.X, chunk_size=chunk_size)
elif layer == DynamoAdataKeyManager.PROTEIN_LAYER:
return DynamoAdataKeyManager._select_layer_gene_chunked_data(
adata.obsm["protein"], chunk_size=chunk_size) if "protein" in adata.obsm_keys() else None
return (
DynamoAdataKeyManager._select_layer_gene_chunked_data(adata.obsm["protein"], chunk_size=chunk_size)
if "protein" in adata.obsm_keys()
else None
)
else:
return DynamoAdataKeyManager._select_layer_gene_chunked_data(adata.layers[layer], chunk_size=chunk_size)
else:
Expand Down Expand Up @@ -172,7 +180,10 @@ def check_if_layer_exist(adata: AnnData, layer: str) -> bool:
return layer in adata.layers

def get_available_layer_keys(
adata: AnnData, layers: str = "all", remove_pp_layers: bool = True, include_protein: bool = True,
adata: AnnData,
layers: str = "all",
remove_pp_layers: bool = True,
include_protein: bool = True,
) -> List[str]:
"""Get the list of available layers' keys. If `layers` is set to all, return a list of all available layers; if
`layers` is set to a list, then the intersetion of available layers and `layers` will be returned."""
Expand Down Expand Up @@ -278,6 +289,7 @@ def aggregate_layers_into_total(

class DynamoVisConfig:
"""Dynamo visualization config class holding static variables to change behaviors of functions globally."""

def set_default_mode(background="white"):
"""Set the default mode for dynamo visualization."""
set_figure_params("dynamo", background=background)
Expand Down Expand Up @@ -340,7 +352,7 @@ def use_default_var_if_none(val: Any, key: str, replace_val: Optional[Any] = Non
Returns:
`val` or config value set in DynamoAdataConfig according to the method description above.
"""
if not key in DynamoAdataConfig.config_key_to_values:
if key not in DynamoAdataConfig.config_key_to_values:
assert KeyError("Config %s not exist in DynamoAdataConfig." % (key))
if val == replace_val:
config_val = DynamoAdataConfig.config_key_to_values[key]
Expand Down Expand Up @@ -431,26 +443,26 @@ def update_data_store_mode(mode: str) -> None:
# register cmap
with warnings.catch_warnings():
warnings.simplefilter("ignore")
if "zebrafish" not in matplotlib.colormaps():
plt.register_cmap("zebrafish", zebrafish_cmap)
if "fire" not in matplotlib.colormaps():
plt.register_cmap("fire", fire_cmap)
if "darkblue" not in matplotlib.colormaps():
plt.register_cmap("darkblue", darkblue_cmap)
if "darkgreen" not in matplotlib.colormaps():
plt.register_cmap("darkgreen", darkgreen_cmap)
if "darkred" not in matplotlib.colormaps():
plt.register_cmap("darkred", darkred_cmap)
if "darkpurple" not in matplotlib.colormaps():
plt.register_cmap("darkpurple", darkpurple_cmap)
if "div_blue_black_red" not in matplotlib.colormaps():
plt.register_cmap("div_blue_black_red", div_blue_black_red_cmap)
if "div_blue_red" not in matplotlib.colormaps():
plt.register_cmap("div_blue_red", div_blue_red_cmap)
if "glasbey_white" not in matplotlib.colormaps():
plt.register_cmap("glasbey_white", glasbey_white_cmap)
if "glasbey_dark" not in matplotlib.colormaps():
plt.register_cmap("glasbey_dark", glasbey_dark_cmap)
if "zebrafish" not in mpl.colormaps():
mpl.colormaps.register(name="zebrafish", cmap=zebrafish_cmap)
if "fire" not in mpl.colormaps():
mpl.colormaps.register(name="fire", cmap=fire_cmap)
if "darkblue" not in mpl.colormaps():
mpl.colormaps.register(name="darkblue", cmap=darkblue_cmap)
if "darkgreen" not in mpl.colormaps():
mpl.colormaps.register(name="darkgreen", cmap=darkgreen_cmap)
if "darkred" not in mpl.colormaps():
mpl.colormaps.register(name="darkred", cmap=darkred_cmap)
if "darkpurple" not in mpl.colormaps():
mpl.colormaps.register(name="darkpurple", cmap=darkpurple_cmap)
if "div_blue_black_red" not in mpl.colormaps():
mpl.colormaps.register(name="div_blue_black_red", cmap=div_blue_black_red_cmap)
if "div_blue_red" not in mpl.colormaps():
mpl.colormaps.register(name="div_blue_red", cmap=div_blue_red_cmap)
if "glasbey_white" not in mpl.colormaps():
mpl.colormaps.register(name="glasbey_white", cmap=glasbey_white_cmap)
if "glasbey_dark" not in mpl.colormaps():
mpl.colormaps.register(name="glasbey_dark", cmap=glasbey_dark_cmap)


_themes = {
Expand Down
23 changes: 15 additions & 8 deletions dynamo/data_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,11 @@ def convert2float(adata: AnnData, columns: List, var: bool = False) -> None:


def load_NASC_seq(
dir: str, type: str = "TPM", delimiter: str = "_", colnames: Optional[List] = None, dropna: bool = False,
dir: str,
type: str = "TPM",
delimiter: str = "_",
colnames: Optional[List] = None,
dropna: bool = False,
) -> AnnData:
"""Function to create an anndata object from NASC-seq pipeline.
Expand Down Expand Up @@ -134,7 +138,7 @@ def load_NASC_seq(
tot_RNA = None
cells_raw, cells = None, None

for f in tqdm(files, desc=f"reading rmse output files:"):
for f in tqdm(files, desc="reading rmse output files:"):
tmp = pd.read_csv(f, index_col=0, sep="\t")

if tot_RNA is None:
Expand Down Expand Up @@ -247,7 +251,7 @@ def aggregate_adata(file_list: list) -> AnnData:

if len(valid_cells) == 0 or len(valid_genes) == 0:
raise Exception(
f"we don't find any gene or cell names shared across different adata objects." f"Please check your data. "
"we don't find any gene or cell names shared across different adata objects."+"Please check your data. "
)

layer_dict = {}
Expand Down Expand Up @@ -323,7 +327,10 @@ def cleanup(adata: AnnData, del_prediction: bool = False, del_2nd_moments: bool


def export_rank_xlsx(
adata: AnnData, path: str = "rank_info.xlsx", ext: str = "excel", rank_prefix: str = "rank",
adata: AnnData,
path: str = "rank_info.xlsx",
ext: str = "excel",
rank_prefix: str = "rank",
) -> None:
import pandas as pd

Expand Down Expand Up @@ -373,15 +380,16 @@ def export_h5ad(adata: AnnData, path: str = "data/processed_data.h5ad") -> None:
for i in fate_keys:
if i is not None:
if "prediction" in adata.uns[i].keys():
adata.uns[i]["prediction"] = {str(index): array for index, array in
enumerate(adata.uns[i]["prediction"])}
adata.uns[i]["prediction"] = {
str(index): array for index, array in enumerate(adata.uns[i]["prediction"])
}
if "t" in adata.uns[i].keys():
adata.uns[i]["t"] = {str(index): array for index, array in enumerate(adata.uns[i]["t"])}

adata.write_h5ad(path)


def import_h5ad(path: str ="data/processed_data.h5ad") -> AnnData:
def import_h5ad(path: str = "data/processed_data.h5ad") -> AnnData:
"""Import a Dynamo h5ad object into anndata."""

adata = read_h5ad(path)
Expand All @@ -397,4 +405,3 @@ def import_h5ad(path: str ="data/processed_data.h5ad") -> AnnData:
adata.uns[i]["t"] = [adata.uns[i]["t"][index] for index in adata.uns[i]["t"]]

return adata

21 changes: 16 additions & 5 deletions dynamo/dynamo_logger.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
from typing import Iterable, Optional

import functools
import logging
import sys
import time
from contextlib import contextmanager
from typing import Iterable, Optional


def silence_logger(name: str) -> None:
Expand Down Expand Up @@ -176,7 +175,13 @@ def error(self, message: str, indent_level: int = 1, *args, **kwargs) -> None:
return self.logger.error(message, *args, **kwargs)

def info_insert_adata(
self, key: str, adata_attr: str = "obsm", log_level: int = logging.NOTSET, indent_level: int = 1, *args, **kwargs
self,
key: str,
adata_attr: str = "obsm",
log_level: int = logging.NOTSET,
indent_level: int = 1,
*args,
**kwargs,
) -> None:
"""Log a message for inserting data into an AnnData object."""
message = "<insert> %s to %s in AnnData Object." % (key, adata_attr)
Expand Down Expand Up @@ -314,7 +319,10 @@ def get_temp_timer_logger() -> Logger:

@staticmethod
def progress_logger(
generator: Iterable, logger: Optional[Logger] = None, progress_name: str = "", indent_level: int = 1,
generator: Iterable,
logger: Optional[Logger] = None,
progress_name: str = "",
indent_level: int = 1,
) -> Iterable:
"""A generator that logs the progress of another generator."""
if logger is None:
Expand Down Expand Up @@ -362,7 +370,10 @@ def main_critical(message: str, indent_level: int = 1) -> None:


def main_tqdm(
generator: Iterable, desc: str = "", indent_level: int = 1, logger: LoggerManager = LoggerManager().main_logger,
generator: Iterable,
desc: str = "",
indent_level: int = 1,
logger: LoggerManager = LoggerManager().main_logger,
) -> Iterable:
"""a TQDM style wrapper for logging something like a loop.
Expand Down
2 changes: 1 addition & 1 deletion dynamo/estimation/csc/utils_velocity.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ def fit_linreg_robust(
f"estimation method {est_method} is not implemented. "
f"Currently supported linear regression methods include `rlm` and `ransac`."
)
except:
except Exception as e:
if intercept:
ym = np.mean(yy)
xm = np.mean(xx)
Expand Down
Loading

0 comments on commit 7e464dc

Please sign in to comment.