Skip to content

Commit 0cb1105

Browse files
author
Pietro ANDREI
committed
updates to accept more techs
1 parent 21ebe76 commit 0cb1105

23 files changed

+595
-96
lines changed

DESCRIPTION

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ Suggests:
5656
MatrixGenerics (>= 1.14.0),
5757
patchwork,
5858
rhdf5,
59+
reticulate,
5960
spatstat.geom,
6061
spatstat.data (>= 3.1.2),
6162
spatstat.explore,

NAMESPACE

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ export(hotspot_overlap)
3131
export(jc_coloc)
3232
export(kandinsky_init)
3333
export(knn_nb)
34+
export(load_g4x_img)
3435
export(membrane_nb)
3536
export(multi_jc)
3637
export(nbCluster)
@@ -44,9 +45,11 @@ export(nnMat)
4445
export(nn_query)
4546
export(populate_sf)
4647
export(prepare_cosmx_seurat)
48+
export(prepare_g4x_seurat)
4749
export(prepare_merscope_seurat)
4850
export(prepare_proseg_seurat)
4951
export(prepare_seurat_other)
52+
export(prepare_slideseq_seurat)
5053
export(prepare_visiumHD_seurat)
5154
export(prepare_visium_seurat)
5255
export(prepare_xenium_seurat)

R/00_Kandinsky_Class_funcs.R

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -533,11 +533,13 @@ as.kandinsky = function(list){
533533
#' Must be one of the following:
534534
#' 'Q': queen contiguity method,check for contact (not overlap) between any edge or side od two polygons (refers to the queen movement rule in chess). Currently only applicable for Visium/Visium-HD data
535535
#' 'C': centroid-based method, use maximum centroid distance threshold to identify spot/cell neighbours
536+
#' 'D': Delaunay triangulation method
536537
#' 'K': KNN method, define k closest neighbours to each spot/cell
537538
#' 'M': membrane-based method, check for the occurrence of a physical contact/intersection within a distance threshold between cell boundaries. Not applicable in the case of Visium spots.
538539
#' @param k numeric, number of nearest neighbours to be set when `nb.method = K`
539540
#' @param d.max numeric, maximum centroid distance threshold to be set when `nb.method = C | M`
540-
#' @param hd.snap numeric, scaling factor used on minimal distance between Visium-HD bins to define neighbour relationships. Only Applied when `nb.method = Q`. Higher `hd.snap` values will give lower distance thresholds.
541+
#' @param soi boolean, whether or not filter Delaunay network to keep sphere of influence (SOI) graph. Default is FALSE
542+
#' @param layers numeric, number of concentric contiguous layers to include in spot neighbourhood. Only Applied when `nb.method = Q`. Default is 1
541543
#' @param ids_other character string specifying variable name to be used as cell identifiers when argument tech is set to "other"
542544
#' @param xcoord_other character string specifying variable name to be used as x coordinates when argument tech is set to "other"
543545
#' @param ycoord_other character string specifying variable name to be used as y coordinates when argument tech is set to "other"
@@ -549,34 +551,43 @@ kandinsky_init = function(seurat=NULL,tech='visium',
549551
tx_path=NULL,
550552
fov_path = NULL,
551553
poly_path = NULL,
552-
nb.method = c('Q','C','K','M'),
554+
nb.method = c('Q','C','D','K','M'),
553555
k=20,d.max=40,
554-
hd.snap=10,
556+
soi=F,
557+
layers = 1,
555558
ids_other = NULL,
556559
xcoord_other=NULL,
557560
ycoord_other=NULL){
558561
if(!inherits(seurat,'Seurat')){
559562
stop('data must be a Seurat object')
560563
}
561-
tech = intersect(tech,c('visium','visium_hd','cosmx','xenium','merscope','other'))
564+
tech = intersect(tech,c('visium','visium_hd','cosmx','xenium','merscope','slideseq','g4x','other'))
562565
if(length(tech) ==0){
563566
stop('You must specify a technology compatible with Kandinsky: visium/visium_hd/cosmx/xenium/merscope/other')
564567
}
565568
kandinsky = list()
566569
kandinsky$platform = tech
567570
if(!is.null(img)){
568571
message('Building Kandinsky slot "img"...')
569-
kandinsky$img = visium2rast(seurat,img_path = img,rm_old_img = F,return.seurat=F,max_dim=img_maxdim)
572+
if(tech %in% c('visium','visium_hd')){
573+
kandinsky$img = visium2rast(seurat,img_path = img,rm_old_img = F,return.seurat=F,max_dim=img_maxdim)
574+
}else if(tech == 'g4x'){
575+
kandinsky$img = load_g4x_img(seurat,img_path = img,rm_old_img = F,return.seurat=F,max_dim=img_maxdim)
576+
}
570577
}else if(is.null(img) & !is.null(seurat@tools$img_path)){
571578
message('Building Kandinsky slot "img"...')
579+
if(tech %in% c('visium','visium_hd')){
572580
kandinsky$img = visium2rast(seurat,img_path = seurat@tools$img_path,rm_old_img = F,return.seurat=F,max_dim=img_maxdim)
581+
}else if(tech == 'g4x'){
582+
kandinsky$img = load_g4x_img(seurat,img_path = seurat@tools$img_path,rm_old_img = F,return.seurat=F,max_dim=img_maxdim)
583+
}
573584
}
574585
message('Building Kandinsky slot "sf"...')
575586
if(tech == 'visium_hd'){
576587
kandinsky$sf = visium2sf(seurat,return.seurat=F,is.hd=T,res=res,binsize=binsize,img=kandinsky$img)
577588
}else if(tech == 'visium'){
578589
kandinsky$sf = visium2sf(seurat,return.seurat=F,is.hd=F,res=res,img=kandinsky$img)
579-
}else if(tech %in% c('cosmx','xenium','merscope')){
590+
}else if(tech %in% c('cosmx','xenium','merscope','slideseq','g4x')){
580591
if(is.null(seurat@tools$poly)){
581592
kandinsky$sf = smi2sf(seurat = seurat,poly_file = poly_path,id='cell_ID',return.seurat = F)
582593
}else{
@@ -599,22 +610,24 @@ kandinsky_init = function(seurat=NULL,tech='visium',
599610
diameter = (mindist/100)*65
600611
kandinsky$sf = sf::st_buffer(kandinsky$sf,dist=diameter/2)
601612
if(nb.method=='Q'){
602-
##Add snap term for contiguity check. The real spot/spot distance should be ~35um, but we can set the snap term to 40um
603-
## In this way we account for any spot misalignment (i.e., spot-spot distance might be slightly higher than 35)
604-
snap = (mindist/100)*40
613+
##Add snap term for contiguity check.
614+
##If we consider each spot as one vertex of an equilateral triangle,
615+
##given the avg. min. distance between two spots, we can set the snap term to the triangle height
616+
snap = (mindist*sqrt(3))/2
605617
}
606618
}else{
607619
kandinsky$sf = sf::st_buffer(kandinsky$sf,dist=mindist/2,endCapStyle = 'SQUARE')
608620
if(nb.method=='Q'){
609-
##Add snap term for contiguity check. There shouldn't be almost any empty space between adjacent Visium-HD bins.
610-
##Therefore, we can set a very small snap term (= 1/10 of minimal bin distance)
611-
snap = (mindist/hd.snap)
621+
##Add snap term for contiguity check.
622+
##There shouldn't be almost any empty space between adjacent Visium-HD bins.
623+
##We can set the snap term equal to ~half of the diagonal of each squared spot
624+
snap = (mindist*0.51*sqrt(2))
612625
}
613626
}
614627
}
615628

616-
if(tech %in% c('visium','visium_hd') & !(nb.method %in% c('Q','C','K'))){
617-
stop('For Visium/Visium-HD data, only the following neighbour methods can be selected: Q(Queen), C(centroid distance), K(K-nearest neighbour)')
629+
if(tech %in% c('visium','visium_hd') & !(nb.method %in% c('Q','C','K','D'))){
630+
stop('For Visium/Visium-HD data, only the following neighbour methods can be selected: Q(Queen), C(centroid distance), K(K-nearest neighbour),D(Delaunay triangulation)')
618631
}
619632

620633
if(length(nb.method) > 1){
@@ -635,37 +648,38 @@ kandinsky_init = function(seurat=NULL,tech='visium',
635648
}else if(nb.method=='C'){
636649
kandinsky$nb = centroid_nb(kandinsky$sf,d.max=d.max)
637650
kandinsky$nb.type = paste0('C_',d.max)
651+
}else if(nb.method=='D'){
652+
kandinsky$nb = tri_nb(kandinsky$sf,soi=soi)
653+
kandinsky$nb.type = paste0('D_',paste0('soi',soi))
638654
}else if(nb.method == 'M'){
639655
kandinsky$nb = membrane_nb(kandinsky$sf,d.max=d.max)
640656
kandinsky$nb.type = paste0('M_',d.max)
641657
}else if(nb.method == 'Q'){
642-
kandinsky$nb = queen_nb(kandinsky$sf,snap=snap)
658+
kandinsky$nb = queen_nb(kandinsky$sf,layers=1,snap=snap)
643659
kandinsky$nb.type = 'Q'
644660
}else{
645-
stop('nb.method parameter must be either "Q", "C", "K", or "M"')
661+
stop('nb.method parameter must be either "Q", "C", "D", "K", or "M"')
646662
}
663+
message('Building Kandinsky slot "tx"...')
647664
if(is.null(seurat@tools$tx)){
648-
message('Building Kandinsky slot "tx"...')
649665
if(is.null(tx_path)){
650666
kandinsky$tx = NULL
651667
}else{
652668
kandinsky$tx = normalizePath(tx_path)
653669
}
654670
}else{
655-
message('Building Kandinsky slot "tx"...')
656671
kandinsky$tx = seurat@tools$tx
657672
seurat@tools$tx = NULL
658673
}
674+
message('Building Kandinsky slot "fov_mask"...')
659675
if(is.null(seurat@tools$fov)){
660-
message('Building Kandinsky slot "fov_mask"...')
661676
if(is.null(fov_path)){
662677
kandinsky$fov_mask = NULL
663678
}else{
664679
fov_info = intersect(c('fov','fov_name'),colnames(seurat@meta.data))
665680
kandinsky$fov_mask = read_fovfile(fov_path,buffer=255,fov_ids = unique(seurat@meta.data[[fov_info]]))
666681
}
667682
}else{
668-
message('Building Kandinsky slot "fov_mask"...')
669683
kandinsky$fov_mask = seurat@tools$fov
670684
seurat@tools$fov = NULL
671685
}

0 commit comments

Comments
 (0)