Skip to content

Commit c0585ac

Browse files
committed
add get_anchor_motif_cell_ids to return cell IDs without computing correlation
1 parent e496501 commit c0585ac

2 files changed

Lines changed: 120 additions & 0 deletions

File tree

SpatialQuery/spatial_gene_covarying.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,86 @@ def compute_covariance_statistics_all_to_all(expr_genes,
577577
return cov_sum, center_ss, neighbor_ss, n_pairs, n_eff
578578

579579

580+
def get_anchor_motif_cell_ids(sq_obj,
581+
ct: str,
582+
motif: Union[str, List[str]],
583+
max_dist: Optional[float] = None,
584+
k: Optional[int] = None,
585+
min_size: int = 0,
586+
) -> dict:
587+
"""
588+
Get cell grouping information for correlation analysis without computing correlations.
589+
590+
Identifies three groups of cells:
591+
1. Center-neighbor pairs where neighbors belong to the specified motif
592+
2. Non-neighbor motif cells (distant motif cells)
593+
3. Center-neighbor pairs for centers without nearby motif
594+
595+
Parameters
596+
----------
597+
sq_obj :
598+
A spatial_query object.
599+
ct : str
600+
Cell type as the center cells.
601+
motif : Union[str, List[str]]
602+
Motif (names of cell types) to be analyzed.
603+
max_dist : Optional[float], default=None
604+
Maximum distance for considering a cell as a neighbor. Use either max_dist or k.
605+
k : Optional[int], default=None
606+
Number of nearest neighbors. Use either max_dist or k.
607+
min_size : int, default=0
608+
Minimum neighborhood size for each center cell (only used when max_dist is specified).
609+
610+
Returns
611+
-------
612+
cell_groups : dict
613+
Dictionary containing cell pairing information:
614+
- 'center_neighbor_motif_pair': array of shape (n_pairs, 2) with
615+
[center_cell_idx, neighbor_cell_idx] pairs for centers with motif neighbors.
616+
- 'non-neighbor_motif_cells': array of cell indices for distant motif cells.
617+
- 'non_motif_center_neighbor_pair': array of shape (n_pairs, 2) with
618+
[center_cell_idx, neighbor_cell_idx] pairs for centers without nearby motif.
619+
Empty array if fewer than 10 pairs found.
620+
"""
621+
motif = motif if isinstance(motif, list) else [motif]
622+
623+
# Step 1: Get center-neighbor pairs for motif
624+
neighbor_result = spatial_utils.get_motif_neighbor_cells(
625+
sq_obj=sq_obj, ct=ct, motif=motif, max_dist=max_dist, k=k, min_size=min_size
626+
)
627+
center_neighbor_pairs = neighbor_result['center_neighbor_pairs']
628+
ct_in_motif = neighbor_result['ct_in_motif']
629+
630+
# Step 2: Derive unique cell sets from pairs
631+
center_cells = np.unique(center_neighbor_pairs[:, 0])
632+
neighbor_cells = np.unique(center_neighbor_pairs[:, 1])
633+
634+
# Step 3: Get non-neighbor motif cells
635+
motif_mask = np.isin(np.array(sq_obj.labels), motif)
636+
all_motif_cells = np.where(motif_mask)[0]
637+
non_neighbor_cells = np.setdiff1d(all_motif_cells, neighbor_cells)
638+
639+
# Remove center type from non-neighbor group for inter-cell-type focus
640+
if ct_in_motif:
641+
center_cell_mask_non = sq_obj.labels[non_neighbor_cells] == ct
642+
non_neighbor_cells = non_neighbor_cells[~center_cell_mask_non]
643+
644+
# Step 4: Get pairs for centers without nearby motif
645+
no_motif_result = spatial_utils.get_all_neighbor_cells(
646+
sq_obj=sq_obj, ct=ct, max_dist=max_dist, k=k, min_size=min_size,
647+
exclude_centers=center_cells, exclude_neighbors=neighbor_cells,
648+
)
649+
center_no_motif_pairs = no_motif_result['center_neighbor_pairs']
650+
651+
cell_groups = {
652+
'center_neighbor_motif_pair': center_neighbor_pairs,
653+
'non-neighbor_motif_cells': non_neighbor_cells,
654+
'non_motif_center_neighbor_pair': center_no_motif_pairs if len(center_no_motif_pairs) >= 10 else np.array([]).reshape(0, 2),
655+
}
656+
657+
return cell_groups
658+
659+
580660
def compute_gene_gene_correlation_adata(sq_obj,
581661
ct: str,
582662
motif: Union[str, List[str]],

SpatialQuery/spatial_query.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -889,6 +889,46 @@ def de_genes(self,
889889

890890
return results_df
891891

892+
def get_anchor_motif_cell_ids(self,
893+
ct: str,
894+
motif: Union[str, List[str]],
895+
max_dist: Optional[float] = None,
896+
k: Optional[int] = None,
897+
min_size: int = 0,
898+
) -> dict:
899+
"""
900+
Get cell grouping information for correlation analysis without computing correlations.
901+
902+
Parameters
903+
----------
904+
ct:
905+
Cell type as the center cells.
906+
motif:
907+
Motif (names of cell types) to be analyzed.
908+
max_dist:
909+
Maximum distance for considering a cell as a neighbor. Use either max_dist or k.
910+
k:
911+
Number of nearest neighbors. Use either max_dist or k.
912+
min_size:
913+
Minimum neighborhood size for each center cell (only used when max_dist is specified).
914+
915+
Returns
916+
-------
917+
cell_groups : dict
918+
Dictionary containing cell pairing information:
919+
- 'center_neighbor_motif_pair': array of [center, neighbor] index pairs.
920+
- 'non-neighbor_motif_cells': distant motif cell indices.
921+
- 'non_motif_center_neighbor_pair': pairs for centers without nearby motif.
922+
"""
923+
return spatial_gene_covarying.get_anchor_motif_cell_ids(
924+
sq_obj=self,
925+
ct=ct,
926+
motif=motif,
927+
max_dist=max_dist,
928+
k=k,
929+
min_size=min_size,
930+
)
931+
892932
def compute_gene_gene_correlation(self,
893933
ct: str,
894934
motif: Union[str, List[str]],

0 commit comments

Comments
 (0)