mechanochat.SEM3#
- class mechanochat.SEM3(ne_per_cell: int, re: float, rd_ratio: float, adata: AnnData | None = None, cluster_key: str = 'leiden', spatial_key: str = 'spatial', xc: ndarray[Any, dtype[_ScalarType_co]] | None = None, ctype: ndarray[Any, dtype[_ScalarType_co]] | None = None, sim_name: str = 'untitled', seed: int = 1)[source]#
Bases:
CellBaseSubcellular Element Method 3D
Create a SEM object
- Parameters:
ne_per_cell (
int) – Number of elements per cellre (
float) – Element radiusrd_ratio (
float) –Cell radius-distance ratio
rd_ratio>2: cell radius < cell distance/2, tissue with gaps
rd_ratio=2: cell radius = cell distance/2, no gaps (confluent tissue)
rd_ratio<2: cell radius > cell distance/2, overcrowded
adata (
Anndata) –Anndata with .obsm[spatial_key] for cell coordinates, .obs[cluster_key] for cell types
If not provided, xc and ctype are required
xc (
Optional[np.ndarray]) – cell coordinates. Ignored, if adata.obsm[spatial_key] is providedctype (
Optional[np.ndarray]) – cell types. Ignored, if adata.obs[cluster_key] is providedcluster_key (
str, default:'leiden') – Key for cell type in .obsspatial_key (
str, default:'spatial') – Key for spatial coordinates in .obsmsim_name (
str, default:'untitled') – Simulation name
- f_cc: csr_matrix#
cell-cell force matrix (symmetric, abs)
- deltax: NDArray#
normalization scaling offset. shape=(1,dim)
- xc: NDArray#
cell coordinates. shape=(nc,dim)
- ecid: NDArray#
(ne)
- Type:
id of cell to which each element belongs. shape
- ceidn: NDArray#
first elements id of each cell (indptr). shape=(nc+1)
Elements of cell i can be retrieve by ceidn[i]:ceidn[i+1].
Number of elements of cell i is ceidn[i+1]-ceidn[i]
- xe: NDArray#
element coordinates. shape=(ne,dim)
- get_param(df_adh: DataFrame, df_stiffness: DataFrame, embedding_key: str = 'X_pca', adh_range: Tuple[float, float] = (0.25, 4.), stiffness_range: Tuple[float, float] = (0.25, 0.5), w: float = 0.75, return_data: bool = False)[source]#
Compute cell mechanical parameters alpha (adhesion) and beta (stiffness) from gene expression data and store them in
self.alpha_csrandself.beta.Computation pipeline
Neighbor detection — build a KD-tree on cell centroids
self.xcand find all cell pairs within a Chebyshev distance of 60 (simulation units). Only neighboring pairs contribute to adhesion and similarity terms.Adhesion score (
adhesion_data) — for each ligand-receptor (LR) pair indf_adh, the per-cell ligand activity l and receptor activity r are computed as the product of min-shifted subunit expression levels (supports multi-subunit ligands/receptors encoded as'gene1_gene2'in the table). The symmetric interaction score for neighbor pair (i, j) is:LR_ij = r_i * l_j + l_i * r_j
Scores from all LR pairs are summed, capped at the 95th percentile to reduce outlier influence, then scaled to
adh_range.Gene expression similarity (
sim_data) — cosine similarity between cell embedding vectors (default: PCA,adata.obsm[embedding_key]) for each neighbor pair, computed as:cos_sim_ij = (X_i · X_j) / (||X_i|| * ||X_j||)
Values are scaled to
adh_range.Alpha matrix — the cell-cell adhesion parameter for pair (i, j) is a weighted combination of expression similarity and LR-based adhesion:
alpha_ij = sim_data_s * (1 - a) + adhesion_data * a
Stored as a symmetric sparse matrix
self.alpha_csrof shape(nc, nc).Beta vector — mean expression of cytoskeleton-related genes in
df_stiffnessper cell, capped at the 95th percentile and scaled tostiffness_range. Stored asself.betaof shape(nc,).
- Parameters:
df_adh (
DataFrame) – Ligand-receptor pair table. Column 0 = ligand gene(s), column 1 = receptor gene(s). Multi-subunit complexes should be joined with'_'(e.g.'ITGA1_ITGB1').df_stiffness (
DataFrame) – Cytoskeleton/stiffness gene table. Column 0 contains gene names whose mean expression determines per-cell stiffness.embedding_key (
str, optional) – Key inadata.obsmfor the cell embedding used to compute gene expression similarity. Default'X_pca'.adh_range (
tupleoffloat, optional) –(min, max)range that bothadhesion_dataandsim_dataare scaled to before combining. Default(0.25, 4.0).stiffness_range (
tupleoffloat, optional) –(min, max)range that stiffness values are scaled to. Default(0.25, 0.5).w (
float, optional) – Mixing weight for adhesion vs. similarity in the alpha parameter.w=1→ pure LR adhesion;w=0→ pure gene expression similarity. Default0.75.return_data (
bool, optional) – IfTrue, return intermediate arrays for inspection. DefaultFalse.
- Returns:
None– Setsself.alpha_csr(sparse(nc, nc)float32) andself.beta((nc,)float32) in place.row_indices, col_indices, lr, sim_data (
only when ``return_data=True``) –row_indices,col_indices— COO indices of neighbor pairs (symmetric);lr— raw (unscaled) symmetric LR adhesion scores;sim_data— raw (unscaled) symmetric cosine similarity values.
- sim_gpu(rm_intra, rm_inter, sigma, dt, T, enable_tqdm=True) None[source]#
Implement the SEM simulation on the GPU.
- Parameters:
rm_intra (
float) – Equilibrium distance of the intracellular element-element potential. Sets the packing of the elements inside a cell.rm_inter (
float) – Equilibrium distance of the intercellular element-element potential. Also the default contact threshold used by compute_contact and the alpha-shape radius (_get_e_radius).sigma (
float) – Amplitude of the thermal noise.dt (
float) – Time step.T (
int) – Number of steps.
- Returns:
Sets the following fields in `sem` (
update `.xe(element coordinates)` and .xc (cell centroids),) – advances .t by T, stores rm_intra / rm_inter in .param, and marks the alpha-shapes as outdated.
Notes
Requires get_param() to have been run, which provides .alpha_csr and .beta.
Intercellular interactions are only evaluated for the cell pairs stored in .alpha_csr and, inside such a pair, only for the elements closer than 30 simulation units along each axis.
NUMBA_CUDA_USE_NVIDIA_BINDING=1 must be set before numba is imported,
- compute_force_chunked(alpha=None, beta=None, gamma=None, chunk_size=300000000) None[source]#
Compute the element-element forces of the current configuration.
All element pairs closer than 30 simulation distance (Chebyshev) are enumerated, and the force of each pair is evaluated on the GPU with the same parameters as sim_gpu. Pairs are processed in chunks to bound the GPU memory.
- Parameters:
chunk_size (
int, default:300000000) – Number of element pairs sent to the GPU per launch. Lower it if the GPU runs out of memory.- Returns:
Sets the following fields in `sem`–.pairs : (n_pairs, 2) element pair indices, pairs[k] = [i, j]
.f_pairs : (n_pairs, dim) the force from j exerted on i for pair k
.f_cc and adata.obsp[‘f_cc’]: (n_cell, n_cell) cell-cell mechanical interaction matrix.
Notes
Requires .param.
sim_gpu() must have been run first.
- compute_cell_forces() None[source]#
Aggregate the element-element forces into a cell-cell mechanical interaction matrix.
The magnitudes of the forces of all element pairs that belong to two different cells are summed, which gives a symmetric measure of how strongly two cells push against or pull on each other. Entries below 0.1 are dropped.
- Returns:
Sets the following fields in `sem`– Adds .f_cc, a symmetric (nc, nc) sparse matrix, and copies it to adata.obsp[‘f_cc’] when the SEM object is linked to an AnnData. Called automatically at the end of compute_force().
- f_pairs_tocsr() Tuple[csr_array, csr_array, csr_array][source]#
Convert force pairs to CSR sparse matrices. Run .compute_force() first
fx_csr[i, j] = fx_{j->i}
row index i : under force column index j : exert force
- Returns:
fx_csr (
csr_array) – Sparse matrix of x-component forcesfy_csr (
csr_array) – Sparse matrix of y-component forces
- compute_shape(alpha: ndarray[Any, dtype[_ScalarType_co]] | float | None = None, xe_data: ndarray[Any, dtype[_ScalarType_co]] | None = None, r: float | None = None, recompute: bool = False)[source]#
Reconstruct the 3D shape of each cell with an alpha-shape.
Every element is replaced by the 12 vertices of an icosahedron of radius
r * scale, giving the point cloud its finite element thickness, and an AlphaShape3 is fitted per cell.- Parameters:
alpha (
floatornumpy.ndarray, optional) – Alpha radius, a scalar shared by all cells or one value per cell. If None, each cell usesmax(r * scale * 1.01, 1.1 * alpha_best), where alpha_best is the smallest radius that keeps the shape connected.xe_data (
numpy.ndarray, optional) – (ne, …) per-element values (e.g. a signal or a pressure) carried over to the vertices of the mesh so that they can be used to color the surface.r (
float, optional) – Element radius used to build the icosahedra. Default: _get_e_radius() / 2, i.e. half of rm_inter.recompute (
bool, default:False) – Rebuild the shapes even if they are already cached. When the shapes exist and only alpha changed, the existing meshes are updated instead of rebuilt.
- Returns:
None– Adds .shp_list (one AlphaShape3 per cell), fills .alpha_radius and updates .alphashape_info.
See also
plotting.alphashape_plot3renders shp_list with PyVista.
- compute_alphashape(alpha: ndarray[Any, dtype[_ScalarType_co]] | float | None = None, ns: int | None = None, r: float | None = None) None#
Compute alpha-shape for each cell
Add .alphashape: List[AlphaShape]
- compute_contact(k: int = 8, d_th: float | None = None, add_key: str = 'contacts') None#
Compute cell-cell contacts
add .contact_matrix (csr_matrix)
stored in adata.obsp[add_key]
- compute_distance(method: str, k: int = 3, return_distances: bool = False) csr_matrix | None#
Compute cell-cell distances in contact matrix
Add .spatial_distances[method] (csr_matrix)
- get_alpha() ndarray[Any, dtype[_ScalarType_co]] | None#
Get alpha radius of each cell
- Returns:
alpha (
Union[np.ndarray,None]) – Alpha radius of each cell if alphashapes have been computed, otherwise None
- get_area() ndarray[Any, dtype[_ScalarType_co]] | None#
Get cell areas
- Returns:
area (
Union[np.ndarray,None]) – Cell areas if alphashapes have been computed, otherwise None
- get_box(cid_list, scaling: bool = True, rotation: Dict | None = None) ndarray[Any, dtype[_ScalarType_co]]#
Bounding box of a group of cells.
- Parameters:
- Returns:
box (
numpy.ndarray) –[xmin, ymin, xmax, ymax], in the format expected by select_cell.
- get_elements(i: int, scaling: bool = True) ndarray[Any, dtype[_ScalarType_co]]#
Get elements of cell i
- get_neighbors(center_i: int)#
Indices of the cells in contact with cell center_i.
Requires compute_contact() to have been run.
- Parameters:
center_i (
int) – Cell index.- Returns:
contact_i (
numpy.ndarray) – Indices of the contacting cells.
- select_cell(box) ndarray[Any, dtype[_ScalarType_co]]#
select cell
- Parameters:
box (
[xl,yl,xu,yu])- Returns:
cid_list (
np.ndarray) – array of selected cells’ index
- set_color(cmap_name: str | None = None, n_colors: int | None = None) None#
Set a color map for sem.ctype (cell types)
- set_vertices_data(xe_data: ndarray[Any, dtype[_ScalarType_co]], n_xs: int = 12)[source]#
Attach per-element values to the vertices of the computed 3D shapes.
Lets a new quantity be mapped onto the surfaces without recomputing them.
- Parameters:
xe_data (
numpy.ndarray) – (ne, …) per-element values.n_xs (
int, default:12) – Number of augmentation points per element used by compute_shape.
- Returns:
None– Updates the vertex data of every AlphaShape3 in .shp_list.
- ctype: NDArray#
cell type code. shape=(nc)
- ctype_list: NDArray#
cell type category. shape=(nct)
- color_list: NDArray#
colors for cell type category. shape=(nct,3)
- alphashape: List[AlphaShape]#
list of alpha-shape object for each cell. len=nc
- alpha_radius: NDArray#
alpha radius of each cell
- compute_convexhull()[source]#
Convex hull of all elements, used as the outer surface of the tissue.
Each element is augmented with the 12 vertices of an icosahedron before the hull is built, so the hull encloses the elements rather than their centers.
- Returns:
None– Adds .convexhull, a scipy.spatial.ConvexHull in spatial units.