---
title: "SPIDER-web"
author: "Cao Lab"
server: shiny
format: 
  dashboard:
    logo: https://ZhengTiger.github.io/picx-images-hosting/PFCapp/Logo-circle.7sn4nqapcl.png
    nav-buttons:
      - icon: github
        href: https://github.com/ZhengTiger/SPIDER-seq
---



# Home

<p style="font-size: 50px; font-weight: bold; text-align: center;">Deciphering the single-cell spatial projectomics and transcriptomics organization in PFC by SPIDER-Seq</p>

<br>

<img src="https://ZhengTiger.github.io/picx-images-hosting/PFCapp/Figure1A.26lgt5fr15.jpg" style="width: 100%;">

<br>
<br>

<p style="font-size: 30px; font-weight: bold; text-align: left;">
Summary
</p>

<p style="font-size: 20px; text-align: justify;">
Deciphering the connectivity, transcriptome, and spatial-omics integrated multi-module brain atlas and the underlying organization principles remains challenging. We developed a cost-effective Single-cell Projectome-transcriptome In situ Deciphering Sequencing (SPIDER-Seq) method by combining viral barcoding tracing with single-cell sequencing and spatial-omics. Leveraging SPIDER-Seq, we delineated a comprehensive integrated single-cell spatial molecular, cellular and projectomic atlas of mouse prefrontal cortex (PFC). The projectomic and transcriptomic cell clusters display distinct organization principle, but are coordinately configured in PFC. These projection neurons gradiently distributed in PFC aligning with their wiring patterns, and importantly, show higher co-projection probability to the downstream nuclei with reciprocal circuit connections. Moreover, we depicted PFC neural transmission map, in which neural transmission molecues (neurotransmitter/neuropeptide and the receptors) distinctly express in different circuits. Finally, we predicted neuron projections by integrated gene profile and spatial information with high accuracy via machine learning. Our study could greatly facilitate to delineating brain multi-module network and understanding neural computation.
</p>


<br>

<p style="font-size: 30px; font-weight: bold; text-align: left;">
Interactively exploring our data
</p>

<p style="font-size: 20px; font-weight: bold; text-align: left;">
scRNAseq
</p>

<p style="font-size: 20px; text-align: justify;">
Our scRNAseq dataset sequenced the PFC of 3 mice. It contains the transcriptome of mouse PFC and the projectome information of 24 PFC targets. Users can browse the following content through the scRNAseq page:
</p>

- scRNAseq Clustering: Select different resolutions to view cell clusters on UMAP
- Gene Expression: Select different genes to view their expression on UMAP
- Barcode Expression: Select different projections to view their expression on UMAP
- Barcode Cell Numbers: View PFC projection cell numbers in different cell clusters



<p style="font-size: 20px; font-weight: bold; text-align: left;">
Spatial data
</p>

<p style="font-size: 20px; text-align: justify;">
Our spatial dataset sequenced 36 slices of mouse PFC. It contains 32 genes and 15 targets information of mouse PFC. Users can browse the following content through the spatial page:
</p>

- Spatial Clustering: Select different resolutions to view the spatial distribution of cell clusters
- Spatial Gene Expression: Select different genes to view their spatial expression
- Spatial Barcode Expression: Select different projections to view their spatial expression
- Barcode Spatial Distribution: View the spatial distribution of PFC projection neurons along anterior-posterior and ventralis-dorsalis axes



<p style="font-size: 20px; font-weight: bold; text-align: left;">
3D
</p>

<p style="font-size: 20px; text-align: justify;">
3D interactive visualization of mouse PFC. Users can browse the following content through the 3D page:
</p>

- Transcriptome 3D Visualization: Select different transcriptome cell clusters to interactively view them in 3D
- Projectome 3D Visualization: Select different Projectome targets to interactively view them in 3D


<p style="font-size: 20px; font-weight: bold; text-align: left;">
Download
</p>

<p style="font-size: 20px; text-align: justify;">
Download the raw and processed data from this study.
</p>


```{r}
#| context: setup
#| warning: false
#| message: false

library(ggplot2)
library(Seurat)
library(shiny)
library(rgl)
library(ggdark)
library(viridis)
library(dplyr)

source("R/Palettes.R")
source('R/includes.R')
Adult.Ex <- readRDS('data/Adult.Ex.rds')
sp.PFC <- readRDS('data/sp.PFC.rds')

clean_cells <- colnames(Adult.Ex)[!(
  (Adult.Ex$Ex_subtype %in% c("CT","NP") & Adult.Ex$BC_num>0) | 
  (Adult.Ex$sample %in% c("Adult2","Adult3") & Adult.Ex$Ex_subtype=="PT" & Adult.Ex$BC_num>0)
  )]
Adult.Ex.clean <- subset(Adult.Ex, cells = clean_cells)

options(rgl.useNULL = TRUE)
```





# scRNAseq {scrolling="true"}

## {.sidebar}

```{r}
selectInput('cluster', 'Select Cluster', c("SubType_Layer","SubType"))
```

```{r}
selectInput('gene', 'Select Gene', rownames(Adult.Ex),
            selected = "Cux2")
```

```{r}
Barcode <- c(
  "ITi-D", "ITi-V", "ITc", "PTi",
  'VIS-I','SSp-I','CP-I','AUD-I','RSP-I',
  'BLA-I','ACB-I','ENTl-I','AId-I','ECT-I',
  'ACB-C','PL-C','ECT-C','ENTl-C',
  'BLA-C','CP-C','AId-C','RSP-C',
  'MD-I','RE-I','DR-I','VTA-I','LHA-I','SC-I')
selectInput('target', 'Select Target', Barcode, selected = "CP-I")
```


## Column

### Row

#### Column

```{r}
plotOutput('cluster_plot')
```

#### Column

```{r}
plotOutput('gene_plot')
```

### Row

#### Column

```{r}
plotOutput('target_plot')
```

#### Column

```{r}
plotOutput('target_bar_plot')
```


```{r}
#| context: server

output$cluster_plot <- renderPlot({
  DimPlot(
    Adult.Ex,
    reduction = 'umap',
    group.by = input$cluster,
    cols = col_cluster[[input$cluster]],
    label = T
  ) +
    coord_fixed()
})

output$gene_plot <- renderPlot({
  FeaturePlot(
    Adult.Ex,
    features = input$gene) +
    coord_fixed()
})

output$target_plot <- renderPlot({
  Barcode <- c(
    "ITi-D", "ITi-V", "ITc", "PTi",
    'VIS-I','SSp-I','CP-I','AUD-I','RSP-I',
    'BLA-I','ACB-I','ENTl-I','AId-I','ECT-I',
    'ACB-C','PL-C','ECT-C','ENTl-C',
    'BLA-C','CP-C','AId-C','RSP-C',
    'MD-I','RE-I','DR-I','VTA-I','LHA-I','SC-I'
    )
  seu <- Adult.Ex.clean
  colnames(seu@meta.data)[match(c("ITi_D_score", "ITi_V_score", "ITc_score", "PTi_score"),colnames(seu@meta.data))] <- c("ITi-D", "ITi-V","ITc","PTi")
  seu@meta.data[,Barcode][is.na(seu@meta.data[,Barcode])] <- 0
  FeaturePlot(
    seu, features = input$target, order = T) +
    coord_fixed()
})

output$target_bar_plot <- renderPlot({
  seu <- Adult.Ex.clean
  if (input$target %in% c("ITi-D", "ITi-V","ITc","PTi")){
    df <- as.data.frame(table(seu@meta.data[,input$cluster][which(seu$Proj_module==input$target)]))
  }else{
    df <- as.data.frame(table(seu@meta.data[,input$cluster][which(seu@meta.data[,input$target]>0)]))
  }
  colnames(df) <- c("Celltypes","Cellnum")
  
  ggplot(df, aes(x=Celltypes, y=Cellnum, fill=Celltypes)) +
    geom_col() +
    scale_fill_manual(values = col_cluster[[input$cluster]]) +
    theme_classic() +
    theme(axis.text.x = element_text(angle = 25, hjust = 1),
          plot.title = element_text(hjust = 0.5)) +
    labs(title = paste("PFC → ",input$target," cell numbers in different cell type",
                       sep=""))
})
```





# Spatial {scrolling="true"}

## {.sidebar}

```{r}
selectInput('sp_slice', 'Select Slice', unique(sp.PFC$slice), 
            selected = "IT_slice_10")
```

```{r}
selectInput('sp_cluster', 'Select Cluster', c("SubType_Layer","SubType"))
```

```{r}
selectInput('sp_gene', 'Select Gene', rownames(sp.PFC),
            selected = "Cux2")
```

```{r}
sp_Barcode <- c(
  "ITi-D", "ITi-V", "ITc", "PTi",
  'VIS-I','SSp-I','CP-I','AUD-I','RSP-I',
  'BLA-I','ACB-I','AId-I','ECT-I',
  'ACB-C','ECT-C','CP-C','AId-C','RSP-C',
  'LHA-I')
selectInput('sp_target', 'Select Target', sp_Barcode)
```


## Column

### Row

#### Column

```{r}
#| fig-width: 10

plotOutput('sp_cluster_plot')
```

#### Column

```{r}
#| fig-width: 10

plotOutput('sp_gene_plot')
```

### Row

#### Column

```{r}
#| fig-width: 10

plotOutput('sp_target_plot')
```

#### Column

```{r}
#| fig-width: 10

plotOutput('sp_target_line_plot')
```

```{r}
#| context: server

output$sp_cluster_plot <- renderPlot({
  df <- data.frame(
    x = sp.PFC$ML_new[sp.PFC$slice==input$sp_slice],
    y = sp.PFC$DV_new[sp.PFC$slice==input$sp_slice],
    type = sp.PFC@meta.data[sp.PFC$slice==input$sp_slice, input$sp_cluster]
  )
  ggplot(df, aes(x=x, y=y, color=type)) +
    geom_point(size=1) +
    scale_color_manual(values = col_cluster[[input$sp_cluster]]) +
    labs(title = paste(input$slice,'cell types in spatial')) +
    guides(color=guide_legend(nrow = 2, byrow = TRUE, reverse = T,
                              override.aes = list(size=2))) +
    coord_fixed() +
    ggdark::dark_theme_void() +
    theme(plot.title = element_text(size = 20, hjust = 0.5),
          legend.position = 'bottom', legend.title=element_blank(),
          legend.text = element_text(size=10))
})

output$sp_gene_plot <- renderPlot({
  df <- data.frame(
    X = sp.PFC$ML_new,
    Y = sp.PFC$DV_new,
    Zscore = scale(log1p(sp.PFC@assays$RNA@counts[input$sp_gene,]))
    )
  df <- df[which(sp.PFC$slice==input$sp_slice),]
  df$Zscore[df$Zscore<0] <- 0
  df$Zscore[df$Zscore>3] <- 3
  df <- df[order(df$Zscore),]
  ggplot(df,aes(x=X,y=Y)) +
    geom_point(aes(colour=Zscore), size=1) +
    scale_color_gradientn(colours = viridis(n = 256, option = "D", direction = 1)) +
    ggdark::dark_theme_void() +
    labs(title = input$sp_gene) +
    theme(plot.title = element_text(size = 20, hjust = 0.5),
          legend.position = 'bottom') +
    coord_fixed()
})

output$sp_target_plot <- renderPlot({
  seu <- sp.PFC
  seu$PTi[is.na(seu$PTi)] <- 0
  seu$ITi_D[is.na(seu$ITi_D)] <- 0
  seu$ITi_V[is.na(seu$ITi_V)] <- 0
  seu$ITc[is.na(seu$ITc)] <- 0
  colnames(seu@meta.data)[match(c("ITi_D","ITi_V"),colnames(seu@meta.data))] <- c("ITi-D","ITi-V")
  df <- data.frame(
    X = seu$ML_new,
    Y = seu$DV_new,
    Zscore = scale(log1p(seu@meta.data[,input$sp_target]))
  )
  df <- df[which(seu$slice==input$sp_slice),]
  df$Zscore[df$Zscore<0] <- 0
  df$Zscore[df$Zscore>3] <- 3
  df <- df[order(df$Zscore),]
  ggplot(df, aes(x=X,y=Y)) +
    geom_point(aes(colour=Zscore), size=1) +
    scale_color_gradientn(colours = viridis(n = 256, option = "E", direction = 1)) +
    ggdark::dark_theme_void() +
    labs(title = input$sp_target) +
    theme(plot.title = element_text(size = 20, hjust = 0.5),
          legend.position = 'bottom') +
    coord_fixed()
})

output$sp_target_line_plot <- renderPlot({
  # AP
  seu <- subset(sp.PFC, cells=colnames(sp.PFC)[which(sp.PFC$ABA_hemisphere=="Left")])
  slice <- unique(seu$slice)
  df <- data.frame('slice'=slice)
  for (i in 1:length(slice)){
    if (input$sp_target %in% c("ITi-D","ITi-V","ITc","PTi")){
      df$cellnum[i] <- length(which(seu$slice==slice[i] & seu$Proj_module==input$sp_target))/length(which(seu$slice==slice[i] & seu$BC_num>0))
    }else{
      df$cellnum[i] <- length(which(seu$slice==slice[i] & seu@meta.data[,input$sp_target]>0))/length(which(seu$slice==slice[i] & seu$BC_num>0))
    }
  }
  df$x <- c(1:36)
  p1 <- ggplot(df, aes(x=x, y=cellnum)) +
    geom_point(alpha=0.5, size=3, color=col_subtype_target[input$sp_target]) +
    geom_smooth(se = F, linewidth=1.5, color=col_subtype_target[input$sp_target]) +
    theme_bw() +
    scale_x_continuous(breaks = seq(0,35,5)) +
    theme(text = element_text(size=15), 
          plot.title = element_text(size = 20, hjust = 0.5)) +
    labs(x='A → P',y='Cell proportion')
  
  # DV
  sp_Barcode <- c("ITi-D", "ITi-V", "ITc", "PTi",
               'VIS-I','SSp-I','CP-I','AUD-I','RSP-I',
               'BLA-I','ACB-I','AId-I','ECT-I',
               'ACB-C','ECT-C','CP-C','AId-C','RSP-C',
               'LHA-I')
  seu <- subset(sp.PFC, cells=colnames(sp.PFC)[which(sp.PFC$ABA_hemisphere=="Left")])
  colnames(seu@meta.data)[match(c("ITi_D","ITi_V"),colnames(seu@meta.data))] <- c("ITi-D","ITi-V")
  bc_slice <- seu@meta.data[,c(sp_Barcode, 'Y','BC_num')]
  bc_slice <- 
    bc_slice |>
    mutate(bin = cut(Y, breaks = 36))
  bin <- sort(unique(bc_slice$bin))
  bc_slice$bin_index <- match(bc_slice$bin, bin)
  df <- data.frame('bin_index'=c(1:36))
  for (i in 1:36){
    df$cellnum[i] <- length(which(bc_slice$bin_index==i &
                                  bc_slice[,input$sp_target]>0))/
    length(which(bc_slice$bin_index==i & bc_slice$BC_num>0))
  }
  df$x <- c(1:36)
  p2 <- ggplot(df, aes(x=x, y=cellnum)) +
    geom_point(alpha=0.5, size=3, color=col_subtype_target[input$sp_target]) +
    geom_smooth(se = F, linewidth=1.5, color=col_subtype_target[input$sp_target]) +
    theme_bw() +
    scale_x_continuous(breaks = seq(0,35,5)) +
    theme(text = element_text(size=15), 
          plot.title = element_text(size = 20, hjust = 0.5)) +
    labs(x='V → D',y='Cell proportion')
  p1/p2
})
```






# 3D

## {.sidebar}

```{r}
sp_Barcode <- c("ITi-D", "ITi-V", "ITc", "PTi",
                'VIS-I','SSp-I','CP-I','AUD-I','RSP-I',
                'BLA-I','ACB-I','AId-I','ECT-I',
                'ACB-C','ECT-C','CP-C','AId-C','RSP-C',
                'LHA-I')
waiter::use_waiter()
selectInput('subtype_3d', 'Select SubType', sort(unique(sp.PFC$SubType)))
selectInput('target_3d', 'Select Target', sp_Barcode)
```


## Column

```{r}
rglwidgetOutput('spatial_subtype', width = "100%")
```


```{r}
#| context: server

observeEvent(input$target_3d,{
  waiter::Waiter$new(id = "spatial_subtype", color="black")$show()
  output$spatial_subtype <- renderRglwidget({
    if (input$target_3d %in% c("ITi-D", "ITi-V", "ITc", "PTi")){
      df_plot <- sp.PFC@meta.data[which(sp.PFC$Proj_module==input$target_3d),]
    }else{
      df_plot <- sp.PFC@meta.data[which(sp.PFC@meta.data[,input$target_3d] > 0),]
    }
    
    open3d()
    bg3d(color = "black")
    par3d(userMatrix = rotationMatrix(-pi/6, -1, 1, 0), zoom = 0.6)
    acr.list <- c("MOs","PL","ORBm","ACAd","ILA","DP","ACAv")
    
    for(acr in acr.list){
      mesh <- mesh3d.allen.annot.from.id(get.id.from.acronym(acr))
      col <- "lightgray"
      shade3d(mesh, col = col, material = list(lit=FALSE), alpha = 0.1)
    }
    
    spheres3d(x = df_plot$ML_new, 
              y = df_plot$DV_new,
              z = df_plot$AP_new,
              col = col_subtype_target[input$target_3d], radius=0.01, alpha=1)
    rglwidget()
  })
})

observeEvent(input$subtype_3d,{
  waiter::Waiter$new(id = "spatial_subtype", color="black")$show()
  output$spatial_subtype <- renderRglwidget({
    df_plot <- sp.PFC@meta.data[which(sp.PFC$SubType == input$subtype_3d),]
    
    open3d()
    bg3d(color = "black")
    par3d(userMatrix = rotationMatrix(-pi/6, -1, 1, 0), zoom = 0.6)
    acr.list <- c("MOs","PL","ORBm","ACAd","ILA","DP","ACAv")
    
    for(acr in acr.list){
      mesh <- mesh3d.allen.annot.from.id(get.id.from.acronym(acr))
      col <- "lightgray"
      shade3d(mesh, col = col, material = list(lit=FALSE), alpha = 0.1)
    }
    
    spheres3d(x = df_plot$ML_new, 
              y = df_plot$DV_new,
              z = df_plot$AP_new,
              col = col_subtype_target[input$subtype_3d], radius=0.01, alpha=1)
    rglwidget()
  })
})
```




# Download

<p style="font-size: 20px; text-align: justify;">
The raw single cell RNA-seq data are available from GEO (<a href="https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE273066">GSE273066</a>).
</p>

<p style="font-size: 20px; text-align: justify;">
The raw image data for this study are available via Hugging Face at <a href="https://huggingface.co/TigerZheng/SPIDER-STdata">TigerZheng/SPIDER-STdata</a>. You can download and unzip the .zip file and then use <a href="https://github.com/hms-dbmi/viv">viv</a> to visualize our raw data.
An example: <a href="https://avivator.gehlenborglab.org/?image_url=https://huggingface.co/TigerZheng/SPIDER-STdata/resolve/main/IT_slice_36_reordered.ome.tiff">IT_slice_36</a>.</p>

<p style="font-size: 20px; text-align: justify;">
The processed data can be downloaded here:</p>

- All cells data: <a href="https://huggingface.co/spaces/TigerZheng/SPIDER-web/resolve/main/data/all.Adult.rds?download=true">all.Adult.rds</a>
- Excitatory data: <a href="https://huggingface.co/spaces/TigerZheng/SPIDER-web/resolve/main/data/Adult.Ex.rds?download=true">Adult.Ex.rds</a>
- Spatial data: <a href="https://huggingface.co/spaces/TigerZheng/SPIDER-web/resolve/main/data/sp.PFC.rds?download=true">sp.PFC.rds</a>




