mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-10-07 00:38:12 +08:00
permit NaN in embedding coordinates (#1631)
* permit NaN in embedding coordinates * lint
This commit is contained in:
@@ -391,13 +391,13 @@ def create_emb(e_name, emb):
|
|||||||
def is_valid_embedding(adata, name, arr):
|
def is_valid_embedding(adata, name, arr):
|
||||||
""" return True if this layout data is a valid array for front-end presentation:
|
""" return True if this layout data is a valid array for front-end presentation:
|
||||||
* ndarray, with shape (n_obs, >= 2), dtype float/int/uint
|
* ndarray, with shape (n_obs, >= 2), dtype float/int/uint
|
||||||
* contains only finite values
|
|
||||||
* follows ScanPy embedding naming conventions
|
* follows ScanPy embedding naming conventions
|
||||||
|
* with all values finite or NaN (no +Inf or -Inf)
|
||||||
"""
|
"""
|
||||||
is_valid = type(name) == str and name.startswith("X_") and len(name) > 2
|
is_valid = type(name) == str and name.startswith("X_") and len(name) > 2
|
||||||
is_valid = is_valid and type(arr) == np.ndarray and arr.dtype.kind in "fiu"
|
is_valid = is_valid and type(arr) == np.ndarray and arr.dtype.kind in "fiu"
|
||||||
is_valid = is_valid and arr.shape[0] == adata.n_obs and arr.shape[1] >= 2
|
is_valid = is_valid and arr.shape[0] == adata.n_obs and arr.shape[1] >= 2
|
||||||
is_valid = is_valid and np.all(np.isfinite(arr))
|
is_valid = is_valid and not np.any(np.isinf(arr)) and not np.all(np.isnan(arr))
|
||||||
return is_valid
|
return is_valid
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -197,12 +197,13 @@ class AnndataAdaptor(DataAdaptor):
|
|||||||
|
|
||||||
def _is_valid_layout(self, arr):
|
def _is_valid_layout(self, arr):
|
||||||
""" return True if this layout data is a valid array for front-end presentation:
|
""" return True if this layout data is a valid array for front-end presentation:
|
||||||
* ndarray, with shape (n_obs, >= 2), dtype float/int/uint
|
* ndarray, dtype float/int/uint
|
||||||
* contains only finite values
|
* with shape (n_obs, >= 2)
|
||||||
|
* with all values finite or NaN (no +Inf or -Inf)
|
||||||
"""
|
"""
|
||||||
is_valid = type(arr) == np.ndarray and arr.dtype.kind in "fiu"
|
is_valid = type(arr) == np.ndarray and arr.dtype.kind in "fiu"
|
||||||
is_valid = is_valid and arr.shape[0] == self.data.n_obs and arr.shape[1] >= 2
|
is_valid = is_valid and arr.shape[0] == self.data.n_obs and arr.shape[1] >= 2
|
||||||
is_valid = is_valid and np.all(np.isfinite(arr))
|
is_valid = is_valid and not np.any(np.isinf(arr)) and not np.all(np.isnan(arr))
|
||||||
return is_valid
|
return is_valid
|
||||||
|
|
||||||
def _validate_data_types(self):
|
def _validate_data_types(self):
|
||||||
@@ -291,7 +292,7 @@ class AnndataAdaptor(DataAdaptor):
|
|||||||
raise PrepareError("No valid layout data.")
|
raise PrepareError("No valid layout data.")
|
||||||
|
|
||||||
# cap layouts to MAX_LAYOUTS
|
# cap layouts to MAX_LAYOUTS
|
||||||
return layouts[0:MAX_LAYOUTS]
|
return valid_layouts[0:MAX_LAYOUTS]
|
||||||
|
|
||||||
def get_embedding_array(self, ename, dims=2):
|
def get_embedding_array(self, ename, dims=2):
|
||||||
full_embedding = self.data.obsm[f"X_{ename}"]
|
full_embedding = self.data.obsm[f"X_{ename}"]
|
||||||
|
|||||||
@@ -328,8 +328,14 @@ class DataAdaptor(metaclass=ABCMeta):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# scale isotropically
|
# scale isotropically
|
||||||
min = embedding.min(axis=0)
|
try:
|
||||||
max = embedding.max(axis=0)
|
min = np.nanmin(embedding, axis=0)
|
||||||
|
max = np.nanmax(embedding, axis=0)
|
||||||
|
except RuntimeError:
|
||||||
|
# indicates entire array was NaN, which should propagate
|
||||||
|
min = np.NaN
|
||||||
|
max = np.NaN
|
||||||
|
|
||||||
scale = np.amax(max - min)
|
scale = np.amax(max - min)
|
||||||
normalized_layout = (embedding - min) / scale
|
normalized_layout = (embedding - min) / scale
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user