├── AnalysisPaper
├── README.md
├── figures
│ ├── figure1.Rmd
│ ├── figure1.html
│ ├── figure2.Rmd
│ ├── figure2.html
│ ├── figure3.Rmd
│ ├── figure3.html
│ ├── figure4.Rmd
│ ├── figure4.html
│ ├── figure5.Rmd
│ ├── figure5.html
│ ├── figure6.Rmd
│ └── figure6.html
├── output
│ ├── figure1
│ │ ├── all_res.csv
│ │ └── sub_res.csv
│ ├── figure2
│ │ ├── DEGs_slice151673.csv
│ │ ├── DEGs_starmap.csv
│ │ ├── distance_to_l1_151507_original.csv
│ │ ├── distance_to_l1_151507_pseudo.csv
│ │ ├── distance_to_l1_151508_original.csv
│ │ ├── distance_to_l1_151508_pseudo.csv
│ │ ├── distance_to_l1_151509_original.csv
│ │ ├── distance_to_l1_151509_pseudo.csv
│ │ ├── distance_to_l1_151510_original.csv
│ │ ├── distance_to_l1_151510_pseudo.csv
│ │ ├── distance_to_l1_151669_original.csv
│ │ ├── distance_to_l1_151669_pseudo.csv
│ │ ├── distance_to_l1_151670_original.csv
│ │ ├── distance_to_l1_151670_pseudo.csv
│ │ ├── distance_to_l1_151671_original.csv
│ │ ├── distance_to_l1_151671_pseudo.csv
│ │ ├── distance_to_l1_151672_original.csv
│ │ ├── distance_to_l1_151672_pseudo.csv
│ │ ├── distance_to_l1_151673_original.csv
│ │ ├── distance_to_l1_151673_pseudo.csv
│ │ ├── distance_to_l1_151674_original.csv
│ │ ├── distance_to_l1_151674_pseudo.csv
│ │ ├── distance_to_l1_151675_original.csv
│ │ ├── distance_to_l1_151675_pseudo.csv
│ │ ├── distance_to_l1_151676_original.csv
│ │ ├── distance_to_l1_151676_pseudo.csv
│ │ ├── distance_to_l1_starmap_original.csv
│ │ ├── distance_to_l1_starmap_pseudo.csv
│ │ ├── pairwise_distance_cor_DLPFC.csv
│ │ └── pairwise_distance_cor_STARmap.csv
│ ├── figure3
│ │ ├── ARI_for_different_cluster_numbers.csv
│ │ ├── Clustering_result_for_cardiomyocytes.csv
│ │ └── DEGs_for_three_clusters_scSpace.csv
│ ├── figure4
│ │ └── ARI_all.csv
│ ├── figure5
│ │ ├── DEGs_between_C3_C5.csv
│ │ ├── GSEA_result.csv
│ │ ├── RCTD_m1.csv
│ │ └── RCTD_m2.csv
│ └── figure6
│ │ ├── DEGs_between_MDM_subcluster.csv
│ │ ├── DSP_limma_result.csv
│ │ ├── Dist_change_ratio.csv
│ │ ├── MT_gene_average_expression.csv
│ │ ├── non_MT_gene_average_expression.csv
│ │ └── ssGSEA_result.csv
└── scripts
│ ├── constructSimulations.R
│ ├── figure1
│ ├── BayesSpace_DRSC_simulation.R
│ ├── SpaGCN_STAGATE_simulation.ipynb
│ ├── scCoGAPS_simulation.ipynb
│ └── scSpace_simulation.ipynb
│ ├── figure2
│ ├── DLPFC_aggregate.R
│ ├── DLPFC_validate.ipynb
│ └── STARmap.ipynb
│ ├── figure3
│ ├── human_heart.ipynb
│ └── human_heart_spatial_informed_clustering.R
│ ├── figure4
│ └── hodge.ipynb
│ ├── figure5
│ ├── melanoma.ipynb
│ └── melanoma_validation.ipynb
│ ├── figure6
│ ├── COVID19.ipynb
│ └── MDM_spatial_informed_clustering.R
│ └── utils.R
├── LICENSE
├── README.md
├── images
└── workflow.jpg
├── requirements.txt
├── scSpace
├── __init__.py
├── models.py
├── scspace.py
└── utils.py
├── setup.py
└── vignettes
├── DLPFC_slice151674.ipynb
├── SCC_p2.ipynb
├── data
├── demo_sc_data.csv
├── demo_sc_meta.csv
├── demo_st_data.csv
└── demo_st_meta.csv
├── demo.ipynb
├── intestines.ipynb
└── melanoma.ipynb
/AnalysisPaper/README.md:
--------------------------------------------------------------------------------
1 | # scSpace reproducibility
2 | Code to reproduce the analysis and figures in the paper [Reconstruction of the cell pseudo-space from
3 | single-cell RNA sequencing data with scSpace](https://www.biorxiv.org/content/10.1101/2022.05.07.491043v1). The scSpace
4 | python package is located [here](https://github.com/ZJUFanLab/scSpace).
5 |
6 | ## Obtaining Datasets
7 | The data used and/or generated in this study can be found on [Google Drive](https://drive.google.com/drive/folders/1_9qS78yDi0agT4x5HQuldg3I1a2WWdYc?usp=sharing).
8 |
9 | ## Running scSpace
10 | The analysis scripts to produced scSpace results can be accessed [here](scripts). For example, the script
11 | [constructSimulations.R](scripts/constructSimulations.R) is used to generate simulated scRNA-seq and spatial transcriptomics
12 | data in benchmarking step.
13 |
14 | ## Generating Main Figures
15 | We provide R Markdown files that were used to create the main figures,
16 | the results consistent with the figures can be accessed [here](output):
17 | * [Performance of scSpace compared with other methods on simulated datasets](https://raw.githack.com/ZJUFanLab/scSpace/master/AnalysisPaper/figures/figure1.html) (Figure 1)
18 | * [Validation of scSpace on human DLPFC 10x Visium data](https://raw.githack.com/ZJUFanLab/scSpace/master/AnalysisPaper/figures/figure2.html) (Figure 2)
19 | * [Validation of scSpace on mouse primary visual cortex STARmap data](https://raw.githack.com/ZJUFanLab/scSpace/master/AnalysisPaper/figures/figure2.html) (Figure 2)
20 | * [Validation of scSpace on human embryonic heart scRNA-seq data](https://raw.githack.com/ZJUFanLab/scSpace/master/AnalysisPaper/figures/figure3.html) (Figure 3)
21 | * [Validation of scSpace on human MTG scRNA-seq data](https://raw.githack.com/ZJUFanLab/scSpace/master/AnalysisPaper/figures/figure4.html) (Figure 4)
22 | * [Application of scSpace on human melanoma scRNA-seq data](https://raw.githack.com/ZJUFanLab/scSpace/master/AnalysisPaper/figures/figure5.html) (Figure 5)
23 | * [Application of scSpace on human COVID-19 scRNA-seq data](https://raw.githack.com/ZJUFanLab/scSpace/master/AnalysisPaper/figures/figure6.html) (Figure 6)
24 |
25 |
26 |
--------------------------------------------------------------------------------
/AnalysisPaper/figures/figure1.Rmd:
--------------------------------------------------------------------------------
1 |
2 | ```{r setup, include=FALSE}
3 | knitr::opts_chunk$set(echo = TRUE)
4 | ```
5 |
6 | # Benckmark scSpace with other methods on 140 simulated datasets
7 | ```{r}
8 | library(ggplot2)
9 | library(ggthemes)
10 | library(ggsignif)
11 | library(mclust)
12 | library(RColorBrewer)
13 | ```
14 |
15 |
16 | ### Load data
17 | ```{r}
18 | # Ground Truth
19 | sim_gt <- readRDS('../data/simulation/sim_groundtruth.RDS')
20 | # scSpace
21 | sim_scspace <- readRDS('../data/simulation/sim_scSpace.RDS')
22 | # Louvain
23 | sim_louvain <- readRDS('../data/simulation/sim_louvain.RDS')
24 | # K-means
25 | sim_kmeans <- readRDS('../data/simulation/sim_kmeans.RDS')
26 | # Hierarchical clustering
27 | sim_hclust <- readRDS('../data/simulation/sim_hclust.RDS')
28 | # scCoGAPS
29 | sim_sccogaps <- readRDS('../data/simulation/sim_scCoGAPS.RDS')
30 | # DR.SC
31 | sim_drsc <- readRDS('../data/simulation/sim_DRSC.RDS')
32 | # BayesSpace
33 | sim_bayesspace <- readRDS('../data/simulation/sim_BayesSpace.RDS')
34 | # SpaGCN
35 | sim_spagcn <- readRDS('../data/simulation/sim_SpaGCN.RDS')
36 | # STAGATE
37 | sim_stagate <- readRDS('../data/simulation/sim_STAGATE.RDS')
38 | ```
39 |
40 | ### Set output dir
41 | ```{r}
42 | output_dir <- '../output/figure1'
43 | if(!dir.exists(output_dir)){
44 | dir.create(output_dir)
45 | } else {
46 | print('Dir already exists!')
47 | }
48 | ```
49 |
50 | ### Calculate ARI of all celltypes
51 | ```{r}
52 | all_res <- data.frame()
53 | for (i in 1:140) {
54 | scspace_tmp <- adjustedRandIndex(sim_gt[[i]]$Group, sim_scspace[[i]]$scSpace)
55 | louvain_tmp <- adjustedRandIndex(sim_gt[[i]]$Group, sim_louvain[[i]]$louvain)
56 | kmeans_tmp <- adjustedRandIndex(sim_gt[[i]]$Group, sim_kmeans[[i]]$kmeans)
57 | hclust_tmp <- adjustedRandIndex(sim_gt[[i]]$Group, sim_hclust[[i]]$hclust)
58 | sccogaps_tmp <- adjustedRandIndex(sim_gt[[i]]$Group, sim_sccogaps[[i]]$scCoGAPS)
59 | drsc_tmp <- adjustedRandIndex(sim_gt[[i]]$Group, sim_drsc[[i]]$spatial.drsc.cluster)
60 | bayesspace_tmp <- adjustedRandIndex(sim_gt[[i]]$Group, sim_bayesspace[[i]]$spatial.cluster)
61 | spagcn_tmp <- adjustedRandIndex(sim_gt[[i]]$Group, sim_spagcn[[i]]$SpaGCN)
62 | stagate_tmp <- adjustedRandIndex(sim_gt[[i]]$Group, sim_stagate[[i]]$STAGATE)
63 |
64 | res_tmp <- data.frame(
65 | simulation = names(sim_gt)[i],
66 | ARI = c(scspace_tmp, louvain_tmp, kmeans_tmp, hclust_tmp, sccogaps_tmp,
67 | drsc_tmp, bayesspace_tmp, spagcn_tmp, stagate_tmp),
68 | method = c('scSpace', 'louvain', 'kmeans', 'hclust', 'scCoGAPS',
69 | 'DR.SC', 'BayesSpace', 'SpaGCN', 'STAGATE')
70 | )
71 |
72 | all_res <- rbind(all_res, res_tmp)
73 | }
74 |
75 | write.csv(all_res, file = paste0(output_dir, '/all_res.csv'))
76 | ```
77 |
78 | ### Plot boxplot of ARI for all celltypes
79 | ```{r fig.height = 4, fig.width = 6, fig.align = 'center'}
80 | all_res$method <- factor(all_res$method, levels = c('scSpace', 'louvain', 'kmeans', 'STAGATE', 'BayesSpace', 'DR.SC', 'scCoGAPS', 'SpaGCN', 'hclust'))
81 |
82 | p <- ggplot(all_res, aes(method, ARI, fill = method)) +
83 | geom_boxplot() +
84 | scale_fill_manual(values = c('#984EA3', '#4DAF4A', '#377EB8', '#FFFF33','#A65628',
85 | '#F781BF', '#10B981', '#999999', '#E41A1C')) +
86 | theme_classic() +
87 | geom_signif(
88 | comparisons = list(c('scSpace', 'louvain'),c('scSpace', 'kmeans'), c('scSpace', 'STAGATE'),
89 | c('scSpace', 'BayesSpace'), c('scSpace', 'DR.SC'),c('scSpace', 'scCoGAPS'),
90 | c('scSpace', 'SpaGCN'), c('scSpace', 'hclust')),
91 | test = 'wilcox.test',
92 | step_increase = 0.1) +
93 | theme(axis.text.x = element_text(angle = 45, hjust = 0.5, vjust = 0.5))
94 |
95 | p
96 | ```
97 |
98 | ### Calculate ARI of all celltypes
99 | ```{r}
100 | sub_res <- data.frame()
101 | for (i in 1:140) {
102 |
103 | if(i %in% c(1, 4, 7, 11, 14, 17, 21, 24, 27, 31, 34, 37, 41, 44, 47)){
104 | subcluster_num <- 2
105 | } else if(i %in% c(2, 5, 8, 9, 12, 15, 18, 19, 22, 25, 28, 29, 32, 35, 38, 39, 42, 45, 48, 49)){
106 | subcluster_num <- 3
107 | } else if(i %in% c(3, 6, 10, 13, 16, 20, 23, 26, 30, 33, 36, 40, 43, 46, 50)){
108 | subcluster_num <- 4
109 | } else if(i %in% c(51:65)){
110 | subcluster_num <- 5
111 | } else if(i %in% c(66:80)){
112 | subcluster_num <- 6
113 | } else if(i %in% c(81:95)){
114 | subcluster_num <- 7
115 | } else if(i %in% c(96:110)){
116 | subcluster_num <- 8
117 | } else if(i %in% c(111:125)){
118 | subcluster_num <- 9
119 | } else if(i %in% c(126:140)){
120 | subcluster_num <- 10
121 | }
122 |
123 | cluster_num <- length(unique(sim_gt[[i]]$Group))
124 |
125 | subcluster_name <- paste0('Group', (1 + cluster_num - subcluster_num):cluster_num)
126 |
127 |
128 | scspace_tmp <- adjustedRandIndex(sim_gt[[i]][sim_gt[[i]]$Group %in% subcluster_name, ]$Group, sim_scspace[[i]][sim_scspace[[i]]$Group %in% subcluster_name, ]$scSpace)
129 | louvain_tmp <- adjustedRandIndex(sim_gt[[i]][sim_gt[[i]]$Group %in% subcluster_name, ]$Group, sim_louvain[[i]][sim_louvain[[i]]$Group %in% subcluster_name, ]$louvain)
130 | kmeans_tmp <- adjustedRandIndex(sim_gt[[i]][sim_gt[[i]]$Group %in% subcluster_name, ]$Group, sim_kmeans[[i]][sim_kmeans[[i]]$Group %in% subcluster_name, ]$kmeans)
131 | hclust_tmp <- adjustedRandIndex(sim_gt[[i]][sim_gt[[i]]$Group %in% subcluster_name, ]$Group, sim_hclust[[i]][sim_hclust[[i]]$Group %in% subcluster_name, ]$hclust)
132 | sccogaps_tmp <- adjustedRandIndex(sim_gt[[i]][sim_gt[[i]]$Group %in% subcluster_name, ]$Group, sim_sccogaps[[i]][sim_sccogaps[[i]]$Group %in% subcluster_name, ]$scCoGAPS)
133 | drsc_tmp <- adjustedRandIndex(sim_gt[[i]][sim_gt[[i]]$Group %in% subcluster_name, ]$Group, sim_drsc[[i]][sim_drsc[[i]]$Group %in% subcluster_name, ]$spatial.drsc.cluster)
134 | bayesspace_tmp <- adjustedRandIndex(sim_gt[[i]][sim_gt[[i]]$Group %in% subcluster_name, ]$Group, sim_bayesspace[[i]][sim_bayesspace[[i]]$Group %in% subcluster_name, ]$spatial.cluster)
135 | spagcn_tmp <- adjustedRandIndex(sim_gt[[i]][sim_gt[[i]]$Group %in% subcluster_name, ]$Group, sim_spagcn[[i]][sim_spagcn[[i]]$Group %in% subcluster_name, ]$SpaGCN)
136 | stagate_tmp <- adjustedRandIndex(sim_gt[[i]][sim_gt[[i]]$Group %in% subcluster_name, ]$Group, sim_stagate[[i]][sim_stagate[[i]]$Group %in% subcluster_name, ]$STAGATE)
137 |
138 | res_tmp <- data.frame(
139 | simulation = names(sim_gt)[i],
140 | subcluster_num = subcluster_num,
141 | ARI = c(scspace_tmp, louvain_tmp, kmeans_tmp, hclust_tmp, sccogaps_tmp,
142 | drsc_tmp, bayesspace_tmp, spagcn_tmp, stagate_tmp),
143 | method = c('scSpace', 'louvain', 'kmeans', 'hclust', 'scCoGAPS',
144 | 'DR.SC', 'BayesSpace', 'SpaGCN', 'STAGATE')
145 | )
146 |
147 | sub_res <- rbind(sub_res, res_tmp)
148 | }
149 |
150 | write.csv(sub_res, file = paste0(output_dir, '/sub_res.csv'))
151 | ```
152 |
153 | ### Plot boxplot of ARI for spatial subclusters
154 | ```{r fig.height = 4, fig.width = 10, fig.align = 'center'}
155 | sub_res$method <- factor(sub_res$method, levels = c('scSpace', 'louvain', 'kmeans', 'STAGATE', 'BayesSpace', 'DR.SC', 'scCoGAPS', 'SpaGCN', 'hclust'))
156 |
157 | p <- ggplot(sub_res, aes(as.factor(subcluster_num), ARI, fill = method)) +
158 | geom_boxplot() +
159 | scale_fill_manual(values = c('#984EA3', '#4DAF4A', '#377EB8', '#FFFF33','#A65628',
160 | '#F781BF', '#10B981', '#999999', '#E41A1C')) +
161 | theme_classic()
162 |
163 | p
164 | ```
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
--------------------------------------------------------------------------------
/AnalysisPaper/figures/figure5.Rmd:
--------------------------------------------------------------------------------
1 |
2 | ```{r setup, include=FALSE}
3 | knitr::opts_chunk$set(echo = TRUE)
4 | ```
5 |
6 | # Sptial analysis of T cell subpopulations in melanoma
7 | ```{r}
8 | library(Seurat)
9 | library(ggplot2)
10 | library(ggthemes)
11 | library(ggsignif)
12 | library(cowplot)
13 | library(dplyr)
14 | library(ggpubr)
15 | library(viridis)
16 | library(cgdsr)
17 | library(survival)
18 | library(survminer)
19 | library(msigdbr)
20 | library(fgsea)
21 | library(tidyverse)
22 | library(spacexr)
23 | library(scatterpie)
24 | library(ggrepel)
25 | ```
26 |
27 |
28 | ### Load data
29 | ```{r}
30 | # Ground Truth
31 | load('../data/melanoma/melanoma.RDS')
32 | ```
33 |
34 | ### Load custom functions
35 | ```{r}
36 | source('../scripts/utils.R')
37 | ```
38 |
39 | ### Set output dir
40 | ```{r}
41 | output_dir <- '../output/figure5'
42 | if(!dir.exists(output_dir)){
43 | dir.create(output_dir)
44 | } else {
45 | print('Dir already exists!')
46 | }
47 | ```
48 |
49 | ### Comparing the pseudo space of T subpopulations consturcted from different ST reference
50 | ```{r fig.height = 8, fig.width = 10, fig.align = 'center'}
51 | sc_meta$scSpace <- sc_meta$Cell_type
52 | sc_meta[sc_meta$Cell_type == 'T cell', ]$scSpace <- paste0('c', (tcell_scspace_sub$scSpace + 1))
53 | sc_meta$m1_pseudo_space1 <- m1_pseudo_space[, 1]
54 | sc_meta$m1_pseudo_space2 <- m1_pseudo_space[, 2]
55 | sc_meta$m2_pseudo_space1 <- m2_pseudo_space[, 1]
56 | sc_meta$m2_pseudo_space2 <- m2_pseudo_space[, 2]
57 | sc_meta[sc_meta$Cell_type != 'T cell' & sc_meta$Cell_type != 'malignant', ]$scSpace <- 'Others'
58 |
59 | # calculate distance between T subpopulations and malignant
60 | sc_sub <- sc_meta[sc_meta$scSpace != 'Others', ]
61 | m1_dist <- cal_dist(
62 | meta = sc_sub,
63 | coord_index = c('m1_pseudo_space1', 'm1_pseudo_space2'),
64 | group_by = 'scSpace',
65 | selected_type = 'malignant',
66 | ignore_select_type = TRUE)
67 | m2_dist <- cal_dist(
68 | meta = sc_sub,
69 | coord_index = c('m2_pseudo_space1', 'm2_pseudo_space2'),
70 | group_by = 'scSpace',
71 | selected_type = 'malignant',
72 | ignore_select_type = TRUE)
73 |
74 | # m1 reference
75 | p1 <- ggplot() +
76 | geom_point(sc_meta[sc_meta$scSpace == 'Others', ], mapping = aes(m1_pseudo_space1, m1_pseudo_space2, color = scSpace), size = 2.5, color = 'grey90') +
77 | geom_point(sc_meta[sc_meta$Cell_type == 'malignant', ], mapping = aes(m1_pseudo_space1, m1_pseudo_space2, color = scSpace), size = 2.5) +
78 | geom_point(sc_meta[sc_meta$Cell_type == 'T cell', ], mapping = aes(m1_pseudo_space1, m1_pseudo_space2, color = scSpace), size = 2.5) +
79 | scale_color_manual(values = c('#3B82F6', '#EF4444', '#854D0E', '#EAB308', '#10B981', '#F97316')) +
80 | ggtitle('Pseudo space (m1)') +
81 | theme(plot.title = element_text(hjust = 0.5)) +
82 | theme_classic()
83 |
84 | m1_dist$group <- factor(m1_dist$group, levels = c('malignant_c5', 'malignant_c4', 'malignant_c2', 'malignant_c1', 'malignant_c3'))
85 | p2 <- ggplot(data=m1_dist, aes(x=group, y=dist, fill=group)) +
86 | geom_boxplot(outlier.shape = NA) +
87 | scale_fill_manual(values = c('#10B981', '#EAB308', '#EF4444', '#3B82F6', '#854D0E')) +
88 | geom_signif(comparisons = list(c('malignant_c5', 'malignant_c4'),
89 | c('malignant_c5', 'malignant_c2'),
90 | c('malignant_c5', 'malignant_c1'),
91 | c('malignant_c5', 'malignant_c3')),
92 | test = "wilcox.test", step_increase=0.1) +
93 | theme_classic() +
94 | ggtitle('Distance to malignant (m1)') +
95 | theme(plot.title = element_text(hjust = 0.5))
96 |
97 | # m2 reference
98 | p3 <- ggplot() +
99 | geom_point(sc_meta[sc_meta$scSpace == 'Others', ], mapping = aes(m2_pseudo_space1, m2_pseudo_space2, color = scSpace), size = 2.5, color = 'grey90') +
100 | geom_point(sc_meta[sc_meta$Cell_type == 'malignant', ], mapping = aes(m2_pseudo_space1, m2_pseudo_space2, color = scSpace), size = 2.5) +
101 | geom_point(sc_meta[sc_meta$Cell_type == 'T cell', ], mapping = aes(m2_pseudo_space1, m2_pseudo_space2, color = scSpace), size = 2.5) +
102 | scale_color_manual(values = c('#3B82F6', '#EF4444', '#854D0E', '#EAB308', '#10B981', '#F97316')) +
103 | ggtitle('Pseudo space (m2)') +
104 | theme(plot.title = element_text(hjust = 0.5)) +
105 | theme_classic()
106 |
107 |
108 | m2_dist$group <- factor(m2_dist$group, levels = c('malignant_c5', 'malignant_c4', 'malignant_c2', 'malignant_c1', 'malignant_c3'))
109 | p4 <- ggplot(data=m2_dist, aes(x=group, y=dist, fill=group)) +
110 | geom_boxplot(outlier.shape = NA) +
111 | scale_fill_manual(values = c('#10B981', '#EAB308', '#EF4444', '#3B82F6', '#854D0E')) +
112 | geom_signif(comparisons = list(c('malignant_c5', 'malignant_c4'),
113 | c('malignant_c5', 'malignant_c2'),
114 | c('malignant_c5', 'malignant_c1'),
115 | c('malignant_c5', 'malignant_c3')),
116 | test = "wilcox.test", step_increase=0.1) +
117 | theme_classic() +
118 | ggtitle('Distance to malignant (m2)') +
119 | theme(plot.title = element_text(hjust = 0.5))
120 |
121 | cowplot::plot_grid(p1, p2, p3, p4)
122 |
123 | ```
124 |
125 | ### Compared with Seurat
126 | ```{r fig.height = 8, fig.width = 10, fig.align = 'center'}
127 | tcell_meta <- sc_meta[sc_meta$Cell_type == 'T cell', ]
128 | tcell_data <- sc_data[, rownames(tcell_meta)]
129 |
130 | # run seurat
131 | sc_obj <- run_Seurat(sc_meta = tcell_meta,
132 | sc_data = tcell_data,
133 | res = 0.36)
134 |
135 | p1 <- DimPlot(sc_obj, pt.size = 1.5, group.by = 'scSpace', cols = c('#3B82F6', '#EF4444', '#854D0E', '#EAB308', '#10B981'))
136 | p2 <- VlnPlot(sc_obj, group.by = 'scSpace', features = c('TK1', 'AURKB', 'BIRC5', 'KIFC1', 'MKI67'), pt.size = 0, cols = c('#3B82F6', '#EF4444', '#854D0E', '#EAB308', '#10B981'))
137 | p3 <- DimPlot(sc_obj, pt.size = 1.5, group.by = 'seurat_clusters', cols = c('#EF4444', '#3B82F6', '#10B981', '#EAB308', '#854D0E'))
138 | p4 <- VlnPlot(sc_obj, group.by = 'seurat_clusters', features = c('TK1', 'AURKB', 'BIRC5', 'KIFC1', 'MKI67'), pt.size = 0, cols = c('#EF4444', '#3B82F6', '#10B981', '#EAB308', '#854D0E'))
139 |
140 | cowplot::plot_grid(p1, p2, p3, p4)
141 |
142 | ```
143 |
144 | ### RCTD results of m1 / m2 ST reference
145 | ```{r fig.height = 5, fig.width = 10, fig.align = 'center'}
146 | st_m1 <- CreateSeuratObject(m1_st_data, meta.data = m1_st_meta)
147 | st_m1 <- NormalizeData(st_m1)
148 | st_m2 <- CreateSeuratObject(m2_st_data, meta.data = m2_st_meta)
149 | st_m2 <- NormalizeData(st_m2)
150 |
151 |
152 | sc_meta[sc_meta$Cell_type == 'T cell', ]$Cell_type <- sc_meta[sc_meta$Cell_type == 'T cell', ]$scSpace
153 | res1 <- run_RCTD(sc_meta = sc_meta, sc_data = sc_data, st_meta = m1_st_meta, st_data = st_m1@assays$RNA@data, celltype_index = 'Cell_type')
154 | res2 <- run_RCTD(sc_meta = sc_meta, sc_data = sc_data, st_meta = m2_st_meta, st_data = st_m2@assays$RNA@data, celltype_index = 'Cell_type')
155 |
156 | res1$xcoord <- m1_st_meta[rownames(res1), ]$xcoord
157 | res1$ycoord <- m1_st_meta[rownames(res1), ]$ycoord
158 | res2$xcoord <- m2_st_meta[rownames(res2), ]$xcoord
159 | res2$ycoord <- m2_st_meta[rownames(res2), ]$ycoord
160 |
161 | write.csv(res1, file = paste0(output_dir, '/RCTD_m1.csv'))
162 | write.csv(res1, file = paste0(output_dir, '/RCTD_m2.csv'))
163 |
164 | colors = c('grey90', '#3B82F6', "#EF4444", "#854D0E", "#EAB308", "#10B981", 'grey90', 'grey90', 'grey90',
165 | '#F97316', 'grey90')
166 |
167 |
168 | p1 <- ggplot() +
169 | geom_scatterpie(
170 | aes(ycoord, xcoord, r=0.5),
171 | data = res1, cols = colnames(res1)[1:(ncol(res1) - 2)],
172 | size = 7, color =NA) +
173 | scale_fill_manual(values = colors) +
174 | coord_fixed() +
175 | theme_classic()
176 |
177 | p2 <- ggplot() +
178 | geom_scatterpie(
179 | aes(ycoord, xcoord, r=0.5),
180 | data = res2, cols = colnames(res1)[1:(ncol(res1) - 2)],
181 | size = 7, color =NA) +
182 | scale_fill_manual(values = colors) +
183 | coord_fixed() +
184 | theme_classic()
185 |
186 | cowplot::plot_grid(p1, p2)
187 |
188 | ```
189 |
190 | ### C3, C5, and malignant proportions
191 | ```{r fig.height = 6, fig.width = 10, fig.align = 'center'}
192 | p1 <- ggplot(res1) +
193 | geom_point(aes(ycoord, xcoord, color = malignant), size = 2) +
194 | scale_color_viridis() +
195 | coord_fixed() +
196 | theme_classic() +
197 | ggtitle('malignant (m1)') +
198 | theme(plot.title = element_text(hjust = 0.5))
199 |
200 | p2 <- ggplot(res1) +
201 | geom_point(aes(ycoord, xcoord, color = c5), size = 2) +
202 | scale_color_viridis() +
203 | coord_fixed() +
204 | theme_classic() +
205 | ggtitle('C5 (m1)') +
206 | theme(plot.title = element_text(hjust = 0.5))
207 |
208 | p3 <- ggplot(res1) +
209 | geom_point(aes(ycoord, xcoord, color = c3), size = 2) +
210 | scale_color_viridis() +
211 | coord_fixed() +
212 | theme_classic() +
213 | ggtitle('C3 (m1)') +
214 | theme(plot.title = element_text(hjust = 0.5))
215 |
216 | p4 <- ggplot(res2) +
217 | geom_point(aes(ycoord, xcoord, color = malignant), size = 2) +
218 | scale_color_viridis() +
219 | coord_fixed() +
220 | theme_classic() +
221 | ggtitle('malignant (m2)') +
222 | theme(plot.title = element_text(hjust = 0.5))
223 |
224 | p5 <- ggplot(res2) +
225 | geom_point(aes(ycoord, xcoord, color = c5), size = 2) +
226 | scale_color_viridis() +
227 | coord_fixed() +
228 | theme_classic() +
229 | ggtitle('C5 (m2)') +
230 | theme(plot.title = element_text(hjust = 0.5))
231 |
232 | p6 <- ggplot(res2) +
233 | geom_point(aes(ycoord, xcoord, color = c3), size = 2) +
234 | scale_color_viridis() +
235 | coord_fixed() +
236 | theme_classic() +
237 | ggtitle('C3 (m2)') +
238 | theme(plot.title = element_text(hjust = 0.5))
239 |
240 | cowplot::plot_grid(p1, p2, p3, p4, p5, p6)
241 |
242 | ```
243 |
244 | ### DEGs between C3 and C5 (volcano plot)
245 | ```{r fig.height = 6, fig.width = 8, fig.align = 'center'}
246 | Idents(sc_obj) <- 'scSpace'
247 | markers <- FindMarkers(sc_obj, ident.1 = 'c5', ident.2 = 'c3', logfc.threshold = 0, min.pct = 0)
248 | markers$gene <- rownames(markers)
249 |
250 | write.csv(markers, file = paste0(output_dir, '/DEGs_between_C3_C5.csv'))
251 |
252 | markers$logp <- -log10(markers$p_val_adj)
253 | markers$group <- 'no_sig'
254 | markers$group[which((markers$p_val_adj < 0.05) & (markers$avg_log2FC > 1))] <- 'up'
255 | markers$group[which((markers$p_val_adj < 0.05) & (markers$avg_log2FC < -1))] <- 'down'
256 | select_gene <- c('IL7R', 'TCF7', 'C3orf33', 'TK1', 'AURKB', 'BIRC5', 'KIFC1', 'MKI67',
257 | 'NME1', 'CDK1', 'TYMS', 'MCM2', 'TPX2', 'TOP2A')
258 | markers$anno <- NA
259 | markers[markers$gene %in% select_gene, ]$anno <- markers[markers$gene %in% select_gene, ]$gene
260 |
261 | p <- ggscatter(markers, x = 'avg_log2FC', y = 'logp', color = 'group', palette = c('#2f5688', 'grey80', '#CC0000'), size = 1.5) +
262 | geom_text_repel(aes(label=anno)) +
263 | theme_classic() +
264 | geom_hline(yintercept = 1.30, linetype = 'dashed') +
265 | geom_vline(xintercept = c(-1, 1), linetype = 'dashed')
266 | p
267 | ```
268 |
269 | ### DEGs between C3 and C5 (heatmap)
270 | ```{r fig.height = 6, fig.width = 8, fig.align = 'center'}
271 | c5_genes <- c(markers[order(markers$avg_log2FC, decreasing = TRUE), ]$gene[1:20], 'CDK2')
272 | c3_genes <- c(markers[order(markers$avg_log2FC, decreasing = FALSE), ]$gene[1:20])
273 | sc_obj_sub <- subset(sc_obj, idents = c('c3', 'c5'))
274 | DoHeatmap(sc_obj_sub, features = c(c3_genes, c5_genes), group.colors = c("#854D0E", "#10B981"))
275 | ```
276 |
277 |
278 | ### Calculate T exhaustion score
279 | ```{r fig.height = 5, fig.width = 10, fig.align = 'center'}
280 | exhaustion_gene <- c('HAVCR2','PDCD1','ENTPD1','TNFRSF9','CCL3','PHLDA1','SIRPG',
281 | 'CTLA4','TIGIT','SNAP47','WARS','CD27','RGS1','TNFRSF1B',
282 | 'CD27-AS1','ACP5','AFAP1L2','MYO7A','AKAP5','ENTPD1-AS1',
283 | 'ADGRG1','TOX','LAYN','CD38','ITGAE','RGS2','CCND2','FKBP1A',
284 | 'MTHFD1','GALM','CSF1','SNX9','ICOS','LYST','MIR155HG','TPI1',
285 | 'SARDH','GZMB','CREM','HLA-DMA','PRDM1','PKM','MYO1E','FUT8','DUSP4','RAB27A',
286 | 'HLA-DRA','UBE2F-SCLY','IGFLR1','CXCL13','IFNG','UBE2F','ITM2A',
287 | 'ID3','CD2BP2','CHST12','CTSD','STAT3','BST2','CXCR6','RALGDS',
288 | 'VCAM1','TRAFD1','SYNGR2','VAPA','IFI35','CD63','NAB1','PARK7',
289 | 'MIR4632','YARS','PRKAR1A','IL2RB','DFNB31','HMGN3','MTHFD2',
290 | 'NDFIP2','PRF1','PRDX5','LAG3','MS4A6A','LINC00299')
291 |
292 | exhaustion_sig <- list(intersect(rownames(sc_obj_sub), exhaustion_gene))
293 | sc_obj_sub <- AddModuleScore(sc_obj_sub, features = exhaustion_sig, name = 'exhaustion_score')
294 |
295 | p1 <- FeaturePlot(sc_obj_sub, features = 'exhaustion_score1', reduction = 'tsne', cols = viridis(9), pt.size = 2.5)
296 |
297 | exhaustion_plot <- data.frame(score = sc_obj_sub$exhaustion_score1,
298 | group = as.character(sc_obj_sub$scSpace))
299 |
300 | p2 <- ggplot(data=exhaustion_plot, aes(x=group, y=score, fill=group)) +
301 | geom_boxplot() +
302 | theme_classic() +
303 | scale_fill_manual(values = c('#854D0E','#10B981')) +
304 | geom_signif(comparisons = list(c("c3","c5")),
305 | map_signif_level=F,
306 | textsize=6,test=wilcox.test,step_increase=0.2)
307 |
308 | cowplot::plot_grid(p1, p2)
309 |
310 | ```
311 |
312 |
313 | ### GSEA
314 | ```{r fig.height = 6, fig.width = 10, fig.align = 'center'}
315 | m_df <- msigdbr(species = "Homo sapiens", category = "H")
316 | fgsea_sets <- m_df %>% split(x = .$gene_symbol, f = .$gs_name)
317 | c5_genes <- markers %>% arrange(desc(avg_log2FC)) %>% dplyr::select(gene, avg_log2FC)
318 | ranks <- deframe(c5_genes)
319 | fgseaRes <- fgsea(fgsea_sets, stats = ranks, nperm = 10000)
320 | fgseaRes_rep <- data.frame(fgseaRes[, c(1:7)])
321 | write.csv(fgseaRes_rep, file = paste0(output_dir, '/GSEA_result.csv'))
322 |
323 | p1 <- plotEnrichment_new(fgsea_sets[["HALLMARK_E2F_TARGETS"]], ranks, ticksSize=0.5) +
324 | theme_classic() +
325 | ggtitle('E2F TARGETS') +
326 | theme(plot.title = element_text(hjust = 0.5))
327 |
328 | p2 <- plotEnrichment_new(fgsea_sets[["HALLMARK_OXIDATIVE_PHOSPHORYLATION"]], ranks, ticksSize=0.5) +
329 | theme_classic() +
330 | ggtitle('OXIDATIVE PHOSPHORYLATION') +
331 | theme(plot.title = element_text(hjust = 0.5))
332 |
333 | p3 <- plotEnrichment_new(fgsea_sets[["HALLMARK_G2M_CHECKPOINT"]], ranks, ticksSize=0.5) +
334 | theme_classic() +
335 | ggtitle('G2M CHECKPOINT') +
336 | theme(plot.title = element_text(hjust = 0.5))
337 |
338 | p4 <- plotEnrichment_new(fgsea_sets[["HALLMARK_DNA_REPAIR"]], ranks, ticksSize=0.5) +
339 | theme_classic() +
340 | ggtitle('DNA REPAIR') +
341 | theme(plot.title = element_text(hjust = 0.5))
342 |
343 | p5 <- plotEnrichment_new(fgsea_sets[["HALLMARK_MYC_TARGETS_V1"]], ranks, ticksSize=0.5) +
344 | theme_classic() +
345 | ggtitle('MYC TARGETS V1') +
346 | theme(plot.title = element_text(hjust = 0.5))
347 |
348 | p6 <- plotEnrichment_new(fgsea_sets[["HALLMARK_MITOTIC_SPINDLE"]], ranks, ticksSize=0.5) +
349 | theme_classic() +
350 | ggtitle('MITOTIC SPINDLE') +
351 | theme(plot.title = element_text(hjust = 0.5))
352 |
353 | cowplot::plot_grid(p1, p2, p3, p4, p5, p6)
354 | ```
355 |
356 | ### Survival analysis
357 | ```{r fig.height = 12, fig.width = 10, fig.align = 'center'}
358 | mycgds <- CGDS('http://www.cbioportal.org/')
359 | all_tcga_studies <- getCancerStudies(mycgds)
360 | skcm_2015 <- 'skcm_tcga'
361 | mycaselist <- getCaseLists(mycgds, skcm_2015)[6,1]
362 | mygeneticprofile <- getGeneticProfiles(mycgds,skcm_2015)[7,1]
363 |
364 | choose_genes <- c('TK1', 'KIFC1', 'AURKB', 'BIRC5', 'MKI67', 'TPX2', 'NME1', 'CDK2')
365 | expr <- getProfileData(mycgds, choose_genes, mygeneticprofile, mycaselist)
366 | clinicaldata <- getClinicalData(mycgds, mycaselist)
367 | dat <- clinicaldata[clinicaldata$OS_MONTHS > 0, ]
368 | dat <- cbind(clinicaldata[, c('OS_STATUS', 'OS_MONTHS')], expr[rownames(clinicaldata), ])
369 | dat <- dat[dat$OS_MONTHS > 0, ]
370 | dat <- dat[!is.na(dat$OS_STATUS), ]
371 | dat$OS_STATUS <- as.character(dat$OS_STATUS)
372 | dat[, -(1:2)] <- apply(dat[, -(1:2)], 2, function(x){ifelse(x > as.numeric(quantile(x)[4]), 'high', 'low')})
373 | attach(dat)
374 | my.surv <- Surv(dat$OS_MONTHS, dat$OS_STATUS == '1:DECEASED')
375 |
376 | # TK1
377 | kmfit <- survfit(my.surv ~ TK1, data = dat)
378 | p1 <- ggsurvplot(kmfit, conf.int = FALSE, pval = TRUE, risk.table = FALSE,
379 | ncensor.plot = FALSE, palette = c('red','blue'))
380 | # KIFC1
381 | kmfit <- survfit(my.surv ~ KIFC1, data = dat)
382 | p2 <- ggsurvplot(kmfit, conf.int = FALSE, pval = TRUE, risk.table = FALSE,
383 | ncensor.plot = FALSE, palette = c('red','blue'))
384 | # AURKB
385 | kmfit <- survfit(my.surv ~ AURKB, data = dat)
386 | p3 <- ggsurvplot(kmfit, conf.int = FALSE, pval = TRUE, risk.table = FALSE,
387 | ncensor.plot = FALSE, palette = c('red','blue'))
388 | # BIRC5
389 | kmfit <- survfit(my.surv ~ BIRC5, data = dat)
390 | p4 <- ggsurvplot(kmfit, conf.int = FALSE, pval = TRUE, risk.table = FALSE,
391 | ncensor.plot = FALSE, palette = c('red','blue'))
392 | # MKI67
393 | kmfit <- survfit(my.surv ~ MKI67, data = dat)
394 | p5 <- ggsurvplot(kmfit, conf.int = FALSE, pval = TRUE, risk.table = FALSE,
395 | ncensor.plot = FALSE, palette = c('red','blue'))
396 | # TPX2
397 | kmfit <- survfit(my.surv ~ TPX2, data = dat)
398 | p6 <- ggsurvplot(kmfit, conf.int = FALSE, pval = TRUE, risk.table = FALSE,
399 | ncensor.plot = FALSE, palette = c('red','blue'))
400 | # NME1
401 | kmfit <- survfit(my.surv ~ NME1, data = dat)
402 | p7 <- ggsurvplot(kmfit, conf.int = FALSE, pval = TRUE, risk.table = FALSE,
403 | ncensor.plot = FALSE, palette = c('red','blue'))
404 | # CDK2
405 | kmfit <- survfit(my.surv ~ CDK2, data = dat)
406 | p8 <- ggsurvplot(kmfit, conf.int = FALSE, pval = TRUE, risk.table = FALSE,
407 | ncensor.plot = FALSE, palette = c('red','blue'))
408 |
409 | cowplot::plot_grid(p1$plot, p2$plot, p3$plot, p4$plot, p5$plot, p6$plot, p7$plot, p8$plot)
410 | ```
411 |
412 |
413 |
--------------------------------------------------------------------------------
/AnalysisPaper/figures/figure6.Rmd:
--------------------------------------------------------------------------------
1 |
2 | ```{r setup, include=FALSE}
3 | knitr::opts_chunk$set(echo = TRUE)
4 | ```
5 |
6 | # Sptial analysis of the invasion of myeloid subpopulations in COVID-19
7 | ```{r}
8 | library(GSVA)
9 | library(Seurat)
10 | library(ggplot2)
11 | library(ggthemes)
12 | library(ggsignif)
13 | library(ggforce)
14 | library(dplyr)
15 | library(reshape2)
16 | library(ggbeeswarm)
17 | library(cowplot)
18 | library(limma)
19 | library(viridis)
20 | library(ggpubr)
21 | library(pheatmap)
22 | ```
23 |
24 |
25 | ### Load data
26 | ```{r}
27 | # Ground Truth
28 | load('../data/covid19/covid19.RDS')
29 | ```
30 |
31 | ### Load custom functions
32 | ```{r}
33 | source('../scripts/utils.R')
34 | ```
35 |
36 | ### Set output dir
37 | ```{r}
38 | output_dir <- '../output/figure6'
39 | if(!dir.exists(output_dir)){
40 | dir.create(output_dir)
41 | } else {
42 | print('Dir already exists!')
43 | }
44 | ```
45 |
46 | ### scRNA-seq overview
47 | ```{r fig.height = 5, fig.width = 10, fig.align = 'center'}
48 | sc_seu <- run_Seurat(sc_meta = sc_meta, sc_data = sc_data, res = 1)
49 | tsne_obj <- sc_seu@meta.data
50 | tsne_obj$tsne1 <- sc_seu@reductions$tsne@cell.embeddings[, 1]
51 | tsne_obj$tsne2 <- sc_seu@reductions$tsne@cell.embeddings[, 2]
52 |
53 | p1 <- ggplot() +
54 | geom_point(tsne_obj, mapping = aes(tsne1,tsne2,color = cell_type_main), size = 2) +
55 | scale_color_manual(values = c('#EF4444', '#3B82F6', '#8B5CF6', '#10B981', '#F97316',
56 | '#84CC16', '#854D0E', '#EAB308', '#D946EF')) +
57 | theme_classic() +
58 | theme(legend.title = element_blank())
59 |
60 | p2 <- ggplot() +
61 | geom_point(tsne_obj, mapping = aes(tsne1,tsne2,color = group), size = 2) +
62 | scale_color_manual(values =c('#A5B4FC', '#F97316')) +
63 | theme_classic() +
64 | theme(legend.title = element_blank())
65 |
66 | cowplot::plot_grid(p1, p2)
67 | ```
68 |
69 | ### Pseudo space of scRNA-seq
70 | ```{r fig.height = 8, fig.width = 10, fig.align = 'center'}
71 | sc_meta$pseudo_space1 <- pseudo_coords[,1]
72 | sc_meta$pseudo_space2 <- pseudo_coords[,2]
73 | sc_meta$cell_type_main_rep <- sc_meta$cell_type_main
74 | sc_meta[sc_meta$cell_type_main_rep %in%
75 | c('APC-like', 'B cells', 'Endothelial cells', 'Fibroblasts',
76 | 'Mast cells', 'Neuronal cells', 'T cells'), ]$cell_type_main_rep <- 'others'
77 |
78 |
79 | p1 <- ggplot() +
80 | geom_point(sc_meta[sc_meta$group == 'Control', ],
81 | mapping = aes(pseudo_space1, pseudo_space2, color = cell_type_main), size = 3) +
82 | scale_color_manual(values = c('#EF4444', '#3B82F6', '#8B5CF6', '#10B981', '#F97316',
83 | '#84CC16', '#854D0E', '#EAB308', '#D946EF')) +
84 | theme_classic() +
85 | ggtitle('Pseudo space (Control)') +
86 | theme(plot.title = element_text(hjust = 0.5)) +
87 | theme(legend.title = element_blank())
88 |
89 | p2 <- ggplot() +
90 | geom_point(sc_meta[sc_meta$group == 'COVID-19', ],
91 | mapping = aes(pseudo_space1, pseudo_space2, color = cell_type_main), size = 3) +
92 | scale_color_manual(values = c('#EF4444', '#3B82F6', '#8B5CF6', '#10B981', '#F97316',
93 | '#84CC16', '#854D0E', '#EAB308', '#D946EF')) +
94 | theme_classic() +
95 | ggtitle('Pseudo space (COVID-19)') +
96 | theme(plot.title = element_text(hjust = 0.5)) +
97 | theme(legend.title = element_blank())
98 |
99 | p3 <- ggplot() +
100 | geom_point(sc_meta[sc_meta$group == 'Control' & (sc_meta$cell_type_main_rep == 'others'), ],
101 | mapping = aes(pseudo_space1, pseudo_space2, color = cell_type_main_rep), size = 3) +
102 | geom_point(sc_meta[sc_meta$group == 'Control' & (sc_meta$cell_type_main_rep != 'others'), ],
103 | mapping = aes(pseudo_space1, pseudo_space2, color = cell_type_main_rep), size = 3) +
104 | scale_color_manual(values = c('#10B981', '#854D0E', 'grey90')) +
105 | theme_classic() +
106 | ggtitle('Pseudo space (Control)') +
107 | theme(plot.title = element_text(hjust = 0.5)) +
108 | theme(legend.title = element_blank())
109 |
110 | p4 <- ggplot() +
111 | geom_point(sc_meta[sc_meta$group == 'COVID-19' & (sc_meta$cell_type_main_rep == 'others'), ],
112 | mapping = aes(pseudo_space1, pseudo_space2, color = cell_type_main_rep), size = 3) +
113 | geom_point(sc_meta[sc_meta$group == 'COVID-19' & (sc_meta$cell_type_main_rep != 'others'), ],
114 | mapping = aes(pseudo_space1, pseudo_space2, color = cell_type_main_rep), size = 3) +
115 | scale_color_manual(values = c('#10B981', '#854D0E', 'grey90')) +
116 | theme_classic() +
117 | ggtitle('Pseudo space (COVID-19)') +
118 | theme(plot.title = element_text(hjust = 0.5)) +
119 | theme(legend.title = element_blank())
120 |
121 | cowplot::plot_grid(p1, p2, p3, p4)
122 |
123 | ```
124 |
125 | ### Calculate distance between Myeloid cells and Alveolar/Airway Epithelial cells of Control and COVID-19 groups
126 | ```{r fig.height = 4, fig.width = 6, fig.align = 'center'}
127 | sc_meta$celltype <- sc_meta$cell_type_fine
128 | sc_meta[sc_meta$cell_type_main == 'T cells', ]$celltype <- 'T cells'
129 | sc_meta[sc_meta$cell_type_main == 'Endothelial cells', ]$celltype <- 'Endothelial cells'
130 | sc_meta[sc_meta$cell_type_main == 'B cells', ]$celltype <- 'B cells'
131 | sc_meta[sc_meta$cell_type_main == 'Fibroblasts', ]$celltype <- 'Fibroblasts'
132 | sc_meta[sc_meta$celltype %in% c('AT1', 'AT2'), ]$celltype <- 'alveolar epithelial cells'
133 | sc_meta[sc_meta$celltype %in% c('Airway basal', 'Airway ciliated', 'Airway club',
134 | 'Airway goblet', 'Airway mucous', 'Tuft-like'), ]$celltype <- 'airway epithelial cells'
135 |
136 | sc_meta$celltype1 <- sc_meta$celltype
137 | sc_meta[sc_meta$celltype1 %in% c('Monocyte-derived macrophages', 'Monocytes',
138 | 'Alveolar macrophages', 'Transitioning MDM') ,]$celltype1 <- 'Myeloid'
139 | sc_meta[sc_meta$celltype1 %in% c('alveolar epithelial cells', 'airway epithelial cells') ,]$celltype1 <- 'Alveolar/Airway Epithelial'
140 |
141 | # calculate pairwise distance
142 | con_dist <- cal_dist(meta = sc_meta[sc_meta$disease__ontology_label == 'normal' &
143 | sc_meta$celltype1 %in% c('Alveolar/Airway Epithelial', 'Myeloid'), ],
144 | coord_index = c('pseudo_space1', 'pseudo_space2'),
145 | group_by = 'celltype1',
146 | selected_type = 'Alveolar/Airway Epithelial',
147 | ignore_select_type = TRUE)
148 |
149 | cov_dist <- cal_dist(meta = sc_meta[sc_meta$disease__ontology_label == 'COVID-19' &
150 | sc_meta$celltype1 %in% c('Alveolar/Airway Epithelial', 'Myeloid'), ],
151 | coord_index = c('pseudo_space1', 'pseudo_space2'),
152 | group_by = 'celltype1',
153 | selected_type = 'Alveolar/Airway Epithelial',
154 | ignore_select_type = TRUE)
155 |
156 | con_dist$type <- 'Control'
157 | cov_dist$type <- 'COVID-19'
158 |
159 | dist_all <- rbind(con_dist, cov_dist)
160 | p <- ggplot(data=dist_all, aes(x=type, y=dist, fill=type)) +
161 | geom_boxplot(outlier.shape = NA) +
162 | scale_fill_manual(values = c('#A5B4FC', '#F97316') )+
163 | theme_classic() +
164 | ggtitle('Distance between Myeloid and Alveolar/Airway Epithelial') +
165 | theme(plot.title = element_text(hjust = 0.5)) +
166 | ggsignif::geom_signif(test = 'wilcox.test', comparisons = list(c('COVID-19', 'Control')))
167 |
168 | p
169 |
170 | ```
171 |
172 | ### Validation using GeoMX DSP data generated by Rendeiro et al. 2021 (doi: 10.1038/s41586-021-03475-6)
173 | ```{r fig.height = 4, fig.width = 6, fig.align = 'center'}
174 | # ssGSEA (doi: 10.1038/s41586-021-03475-6)
175 | # create cell-type signature gene sets
176 | Idents(sc_seu) <- 'cell_type_main'
177 | marker <- FindAllMarkers(sc_seu, only.pos = TRUE, assay = 'RNA', logfc.threshold = 0.5)
178 | marker <- marker[marker$p_val_adj < 0.05, ]
179 | genesets <- list(Fibroblasts=marker[marker$cluster=='Fibroblasts', ]$gene,
180 | Mast=marker[marker$cluster=='Mast cells', ]$gene,
181 | Epithelial=marker[marker$cluster=='Epithelial cells', ]$gene,
182 | Tcells=marker[marker$cluster=='T cells', ]$gene,
183 | Myeloid=marker[marker$cluster=='Myeloid', ]$gene,
184 | Endothelial=marker[marker$cluster=='Endothelial cells', ]$gene,
185 | Bcells=marker[marker$cluster=='B cells', ]$gene,
186 | DC=marker[marker$cluster=='APC-like', ]$gene,
187 | Neuronal=marker[marker$cluster=='Neuronal cells', ]$gene)
188 |
189 | # DSP data
190 | colnames(dsp_data) <- rownames(dsp_meta)
191 | dsp_meta <-dsp_meta[dsp_meta$disease != 'Non-viral', ]
192 | dsp_meta[dsp_meta$disease != 'Normal', ]$disease <- 'COVID-19'
193 | dsp_meta[dsp_meta$disease == 'Normal', ]$disease <- 'Control'
194 | dsp_data <- dsp_data[, rownames(dsp_meta)]
195 | dsp_data <- as.matrix(dsp_data)
196 | # run ssGSEA
197 | ssgsea_score <- gsva(dsp_data, genesets, method = "ssgsea", ssgsea.norm = TRUE, verbose = TRUE)
198 | ssgsea_score <- data.frame(t(ssgsea_score))
199 | ssgsea_score_plot <- ssgsea_score
200 | ssgsea_score_plot$disease <- dsp_meta$disease
201 | ssgsea_score_plot <- melt(ssgsea_score_plot)
202 |
203 | p <- ggplot(ssgsea_score_plot[ssgsea_score_plot$variable == 'Myeloid',],
204 | aes(disease, value, color = disease))+
205 | geom_boxplot() +
206 | geom_beeswarm(aes(fill = disease), shape=21, colour = "black", size = 3, cex = 2)+
207 | scale_color_manual(values= c('#A5B4FC', '#F97316')) +
208 | scale_fill_manual(values= c('#A5B4FC', '#F97316')) +
209 | theme_classic() +
210 | ggsignif::geom_signif(comparisons = list(c('Control', 'COVID-19')),
211 | step_increase = 0.3, color = "black", test = 'wilcox.test')
212 | p
213 |
214 | ssgsea_score_plot <- ssgsea_score_plot[ssgsea_score_plot$variable == 'Myeloid', ]
215 | write.csv(ssgsea_score_plot, file = paste0(output_dir, '/ssGSEA_result.csv'))
216 | ```
217 |
218 | ```{r fig.height = 4, fig.width = 6, fig.align = 'center'}
219 | # CYBERSORTx
220 | cybersort_res <- read.csv('../data/covid19/CIBERSORTx_Job1_Results.csv', row.names = 1)
221 | cybersort_res <- cybersort_res[, 1:9]
222 | cybersort_res$disease <- dsp_meta[rownames(cybersort_res), ]$disease
223 | cybersort_res <- melt(cybersort_res)
224 |
225 | p <- ggplot(cybersort_res[cybersort_res$variable == 'Myeloid',],
226 | aes(disease, value, color = disease))+
227 | geom_boxplot() +
228 | geom_beeswarm(aes(fill = disease), shape=21, colour = "black", size = 3, cex = 2)+
229 | scale_color_manual(values= c('#A5B4FC', '#F97316')) +
230 | scale_fill_manual(values= c('#A5B4FC', '#F97316')) +
231 | theme_classic() +
232 | ggsignif::geom_signif(comparisons = list(c('Control', 'COVID-19')),
233 | step_increase = 0.3, color = "black", test = 'wilcox.test')
234 | p
235 | ```
236 |
237 | ```{r fig.height = 4, fig.width = 6, fig.align = 'center'}
238 | # Calculate the COVID-19 signatures using DSP data
239 | # limma
240 | dsp_data <- dsp_data[intersect(rownames(dsp_data), rownames(sc_data)), ]
241 | list <- dsp_meta$disease %>% factor(., levels = c("Control", "COVID-19"), ordered = F)
242 | list <- model.matrix(~factor(list) + 0)
243 | colnames(list) <- c("Control", "COVID")
244 | df.fit <- lmFit(dsp_data, list)
245 | df.matrix <- makeContrasts(COVID - Control , levels = list)
246 | fit <- contrasts.fit(df.fit, df.matrix)
247 | fit <- eBayes(fit)
248 | limma_res <- topTable(fit,n = Inf, adjust = "fdr")
249 |
250 | # ggscatter
251 | limma_res_plot <- limma_res
252 | limma_res_plot$gene <- rownames(limma_res_plot)
253 | limma_res_plot$logp <- -log10(limma_res_plot$adj.P.Val)
254 | limma_res_plot$group <- 'no_sig'
255 | limma_res_plot$group[which((limma_res_plot$adj.P.Val < 0.05) & (limma_res_plot$logFC > 0.5))] <- 'up'
256 | limma_res_plot$group[which((limma_res_plot$adj.P.Val < 0.05) & (limma_res_plot$logFC < -0.5))] <- 'down'
257 | p <- ggscatter(limma_res_plot, x = 'logFC', y = 'logp', color = 'group',
258 | palette = c('#2f5688', 'grey80', '#CC0000'), size = 2, label = 'gene',
259 | label.select = rownames(limma_res)[order(limma_res$logFC, decreasing=TRUE)[1:10]],
260 | font.label = c(8, 'plain')) +
261 | theme_classic() +
262 | geom_hline(yintercept = 1.30, linetype = 'dashed') +
263 | geom_vline(xintercept = c(-0.5, 0.5), linetype = 'dashed')
264 |
265 | p
266 |
267 | write.csv(limma_res_plot, file = paste0(output_dir, '/DSP_limma_result.csv'))
268 | ```
269 |
270 | ```{r fig.height = 4, fig.width = 6, fig.align = 'center'}
271 | # Compare the COVID-19 signatures score between Myeloid cells (near to Alveolar/Airway Epithelial) and Myeloid cells (far from Alveolar/Airway Epithelial)
272 |
273 | # COVID-19 signatures
274 | covid19_signatures <- list(rownames(limma_res[limma_res$logFC > 0.5, ]))
275 |
276 | # Extract Alveolar/Airway Epithelial cells and Myeloid cells from COVID-19 group
277 | mye_epi <- sc_meta[sc_meta$celltype %in% c('airway epithelial cells','alveolar epithelial cells') |
278 | sc_meta$celltype1 == 'Myeloid', ]
279 | mye_epi <- mye_epi[mye_epi$disease__ontology_label == 'COVID-19', ]
280 | dist_df <- data.frame(as.matrix(dist(mye_epi[, c('pseudo_space1', 'pseudo_space2')])))
281 |
282 | # Myeloid to Alveolar/Airway Epithelial (far: distance > median(distance); near: distance <= median(distance))
283 | dist_df <- dist_df[rownames(mye_epi[mye_epi$celltype1 == 'Myeloid', ]),
284 | rownames(mye_epi[mye_epi$celltype1 == 'Alveolar/Airway Epithelial', ])]
285 | dist_mean <- apply(dist_df, 1, mean)
286 | mye_near_to_epi <- names(dist_mean[dist_mean <= median(dist_mean)])
287 | mye_far_from_epi <- names(dist_mean[dist_mean > median(dist_mean)])
288 |
289 | mye_meta <- mye_epi[mye_epi$celltype1 == 'Myeloid', ]
290 | mye_meta$type <- NA
291 | mye_meta[mye_near_to_epi, ]$type <- 'Myeloid (Near)'
292 | mye_meta[mye_far_from_epi, ]$type <- 'Myeloid (Far)'
293 |
294 | # Calculate COVID-19 signatures socre
295 | mye_data <- sc_data[, rownames(mye_meta)]
296 | seu_obj <- CreateSeuratObject(mye_data, meta.data = mye_meta)
297 | seu_obj <- AddModuleScore(seu_obj, features = covid19_signatures, name = 'DSP')
298 | module_score_df <- seu_obj@meta.data
299 |
300 | p <- ggplot(data=module_score_df, aes(x=type, y=DSP1, fill=type)) +
301 | geom_boxplot(outlier.shape = NA) +
302 | theme_classic() +
303 | scale_fill_manual(values = c('#E41A1C','#377EB8')) +
304 | ggtitle('COVID-19 Signatures Socre') +
305 | theme(plot.title = element_text(hjust = 0.5)) +
306 | geom_signif(comparisons = list(c('Myeloid (Near)', 'Myeloid (Far)')), test = 'wilcox.test')
307 | p
308 | ```
309 |
310 | ```{r fig.height = 6, fig.width = 8, fig.align = 'center'}
311 | # DEGs of Myeloid cells (near to Alveolar/Airway Epithelial)
312 | Idents(seu_obj) <- 'type'
313 | p <- VlnPlot(seu_obj, features = c('B2M', 'HLA-A', 'HLA-B', 'HLA-C', 'HLA-DRA', 'HLA-E'), cols = c('#E41A1C', '#377EB8'), pt.size = 0)
314 | p
315 | ```
316 |
317 | ### Calculate distance between Myeloid subclusters and Alveolar/Airway Epithelial cells
318 | ```{r fig.height = 5, fig.width = 10, fig.align = 'center'}
319 | mye_epi <- sc_meta[sc_meta$celltype %in% c('airway epithelial cells','alveolar epithelial cells') |
320 | sc_meta$celltype1 == 'Myeloid', ]
321 | mye_epi$celltype2 <- mye_epi$celltype
322 | mye_epi[mye_epi$celltype1 == 'Alveolar/Airway Epithelial', ]$celltype2 <- 'Alveolar/Airway Epithelial'
323 |
324 | # calculate pairwise distance
325 | con_dist <- cal_dist(meta = mye_epi[mye_epi$disease__ontology_label == 'normal', ],
326 | coord_index = c('pseudo_space1', 'pseudo_space2'),
327 | group_by = 'celltype2',
328 | selected_type = 'Alveolar/Airway Epithelial',
329 | ignore_select_type = TRUE)
330 |
331 | cov_dist <- cal_dist(meta = mye_epi[mye_epi$disease__ontology_label == 'COVID-19', ],
332 | coord_index = c('pseudo_space1', 'pseudo_space2'),
333 | group_by = 'celltype2',
334 | selected_type = 'Alveolar/Airway Epithelial',
335 | ignore_select_type = TRUE)
336 |
337 | con_dist$type <- 'Control'
338 | cov_dist$type <- 'COVID-19'
339 | dist_all <- rbind(con_dist, cov_dist)
340 |
341 | dist_all$group <- gsub('Alveolar/Airway Epithelial_', '', dist_all$group)
342 | dist_all$group <- gsub('Alveolar macrophages', 'AM', dist_all$group)
343 | dist_all$group <- gsub('Monocyte-derived macrophages', 'MDM', dist_all$group)
344 | dist_all$group <- gsub('Monocytes', 'Mon', dist_all$group)
345 | dist_all$group <- gsub('Transitioning MDM', 'TMDM', dist_all$group)
346 | p1 <- ggplot(data=dist_all, aes(x=group, y=dist, fill=type)) +
347 | geom_boxplot(outlier.shape = NA) +
348 | scale_fill_manual(values = c('#A5B4FC', '#F97316') )+
349 | theme_classic() +
350 | ggtitle('Distance between Myeloid subclusters and Alveolar/Airway Epithelial') +
351 | theme(plot.title = element_text(hjust = 0.5)) +
352 | ggpubr::stat_compare_means(aes(group=type), method = 'wilcox.test')
353 |
354 | # distance change ratio between COVID-19 and Control group
355 | distance_median_control <- aggregate(dist_all[dist_all$type == 'Control', ]$dist,
356 | by=list(dist_all[dist_all$type == 'Control', ]$group),median)
357 | distance_median_coviid19 <- aggregate(dist_all[dist_all$type == 'COVID-19', ]$dist,
358 | by=list(dist_all[dist_all$type == 'COVID-19', ]$group),median)
359 |
360 | distance_chage_ratio <- data.frame(celltype = distance_median_control$Group.1,
361 | control_median = distance_median_control$x,
362 | covid19_median = distance_median_coviid19$x)
363 |
364 | distance_chage_ratio$ratio <- (distance_chage_ratio$covid19_median -
365 | distance_chage_ratio$control_median) / distance_chage_ratio$control_median
366 |
367 | distance_chage_ratio$celltype <- factor(distance_chage_ratio$celltype, levels = c('TMDM', 'MDM', 'AM', 'Mon'))
368 |
369 | write.csv(distance_chage_ratio, file = paste0(output_dir, '/Dist_change_ratio.csv'))
370 |
371 | p2 <- ggplot(distance_chage_ratio) +
372 | geom_bar(aes(celltype, -ratio, fill=celltype, color=celltype), stat = 'identity') +
373 | scale_fill_manual(values = c('#8B5CF6', '#3B82F6', '#F97316', '#EAB308')) +
374 | scale_color_manual(values = c('black', 'black', 'black', 'black')) +
375 | ggtitle('Distance change') +
376 | theme(plot.title = element_text(hjust = 0.5)) +
377 | theme_classic()
378 |
379 | cowplot::plot_grid(p1, p2)
380 |
381 | ```
382 |
383 | ### TMDM/MDM subclusters analysis
384 | ```{r fig.height = 5, fig.width = 10, fig.align = 'center'}
385 | sc_meta_mdm <- sc_meta[sc_meta$cell_type_fine == 'Monocyte-derived macrophages' | sc_meta$cell_type_fine == 'Transitioning MDM', ]
386 | sc_meta_mdm$scSpace <- mdm_meta$scspace
387 | sc_data_mdm <- sc_data[, rownames(sc_meta_mdm)]
388 |
389 | mdm <- run_Seurat(sc_meta = sc_meta_mdm, sc_data = sc_data_mdm, res = 0.35)
390 | mdm$scSpace <- paste0('C_', (mdm$scSpace + 1))
391 | mdm$seurat_clusters <- paste0('C_', as.numeric(mdm$seurat_clusters))
392 | mdm_meta_new <- mdm@meta.data
393 | mdm_meta_new$tsne1 <- mdm@reductions$tsne@cell.embeddings[, 1]
394 | mdm_meta_new$tsne2 <- mdm@reductions$tsne@cell.embeddings[, 2]
395 |
396 | p1 <- ggplot() +
397 | geom_point(mdm_meta_new, mapping = aes(tsne1,tsne2,color = scSpace), size = 3) +
398 | scale_color_manual(values = c('#3B82F6', '#EF4444', '#C798EE', '#EAB308', '#F97316', '#854D0E')) +
399 | theme_classic() +
400 | ggtitle('MDM/TMDM subclusters') +
401 | theme(plot.title = element_text(hjust = 0.5)) +
402 | theme(legend.title = element_blank())
403 |
404 | # Calculate distance between MDM/TMDM subclusters and Alveolar/Airway Epithelial
405 | epi_meta <- sc_meta[sc_meta$celltype %in% c('airway epithelial cells','alveolar epithelial cells'), ]
406 | dist_df <- data.frame(
407 | pseudo_space1 = c(mdm_meta_new$pseudo_space1, epi_meta$pseudo_space1),
408 | pseudo_space2 = c(mdm_meta_new$pseudo_space2, epi_meta$pseudo_space2),
409 | celltype = c(mdm_meta_new$scSpace, epi_meta$celltype1))
410 |
411 | dist_res <- cal_dist(meta = dist_df,
412 | coord_index = c('pseudo_space1', 'pseudo_space2'),
413 | group_by = 'celltype',
414 | selected_type = 'Alveolar/Airway Epithelial',
415 | ignore_select_type = TRUE)
416 |
417 | dist_res$group <- gsub('Alveolar/Airway Epithelial_', '', dist_res$group)
418 | dist_res$group <- factor(dist_res$group, levels = c('C_4', 'C_2', 'C_5', 'C_6', 'C_3', 'C_1'))
419 | p2 <- ggplot(data=dist_res, aes(x=group, y=dist, fill=group)) +
420 | geom_boxplot(outlier.shape = NA) +
421 | scale_fill_manual(values = c('#EAB308', '#EF4444', '#F97316', '#854D0E', '#C798EE', '#3B82F6')) +
422 | theme_classic() +
423 | ggtitle('Distance between MDM/TMDM subclusters and Alveolar/Airway Epithelial') +
424 | theme(plot.title = element_text(hjust = 0.5)) +
425 | geom_signif(comparisons = list(c('C_4', 'C_2'), c('C_4', 'C_5'), c('C_4', 'C_6'),
426 | c('C_4', 'C_3'), c('C_4', 'C_1')),
427 | test = 'wilcox.test', step_increase=0.1)
428 |
429 | cowplot::plot_grid(p1, p2)
430 | ```
431 |
432 | ### DEGs between MDM/TMDM subclusters
433 | ```{r fig.height = 8, fig.width = 8, fig.align = 'center'}
434 | Idents(mdm) <- 'scSpace'
435 | mdm@active.ident <- factor(mdm@active.ident, levels = c('C_1', 'C_2', 'C_3', 'C_4', 'C_5', 'C_6'))
436 | all_markers <- FindAllMarkers(mdm, assay = 'RNA', only.pos = TRUE, logfc.threshold = 0.5)
437 | all_markers <- all_markers[all_markers$p_val_adj < 0.05, ]
438 |
439 | write.csv(all_markers, file = paste0(output_dir, '/DEGs_between_MDM_subcluster.csv'))
440 |
441 | top10 <- all_markers %>% group_by(cluster) %>% top_n(n = 10, wt = avg_log2FC)
442 | # heatmap
443 | DoHeatmap(mdm, features = top10$gene, group.colors = c('#EAB308', '#EF4444', '#F97316', '#854D0E', '#C798EE', '#3B82F6'))
444 | ```
445 |
446 | ```{r fig.height = 9, fig.width = 6, fig.align = 'center'}
447 | # Featureplot
448 | p <- FeaturePlot(mdm, reduction = 'tsne', features = c('F13A1', 'SEMA3C', 'ZNF331', 'MT-ND3', 'HSP90AA1', 'LSAMP'))
449 | p
450 | ```
451 |
452 | ### Average expression of MT genes (C4 markers)
453 | ```{r fig.height = 6, fig.width = 6, fig.align = 'center'}
454 | c4_marker_mito <- c("MT-ND1", "MT-ND4", "MT-CYB", "MT-ATP8", "MT-ND3", "MT-ND5", "MT-ND2", "MT-ATP6", "MT-CO3",
455 | "MT-ND6", "MT-ND4L", "MT-CO2", "MT-CO1")
456 | gene_to_heatmap <- AverageExpression(mdm, slot = 'count', features = c4_marker_mito)$RNA
457 |
458 | write.csv(gene_to_heatmap, file = paste0(output_dir, '/MT_gene_average_expression.csv'))
459 |
460 | pheatmap(t(gene_to_heatmap),
461 | cluster_rows = FALSE,
462 | cluster_cols = FALSE,
463 | border_color = 'white',
464 | color = colorRampPalette(viridis(9))(100),
465 | cellwidth = 20,
466 | cellheight = 20)
467 | ```
468 |
469 | ### Average expression of non-MT genes (C4 markers)
470 | ```{r fig.height = 4, fig.width = 10, fig.align = 'center'}
471 | c4_marker_non_mito <- c("B2M", "APOE", "LNCAROD", "C1QA", "TMSB4X", "NUPR1", "TMEM51", "KCTD12", "RNASE1",
472 | "GRN", "ZBTB1", "SSBP3", "HLA-DRA", "CD74", "FTL", "CEBPD", "EPSTI1", "NLRC5", "ORMDL1",
473 | "SBNO2", "NUDCD3", "CORO2A", "QSOX1", "ST8SIA4", "MAFB", "CTSS", "BTG1", "CLIC4",
474 | "CD14", "CARD8", "NFATC3", "RAPGEF6", "INO80D", "ZNF292", "PIK3AP1")
475 | gene_to_heatmap <- AverageExpression(mdm, slot = 'count', features = c4_marker_non_mito)$RNA
476 |
477 | write.csv(gene_to_heatmap, file = paste0(output_dir, '/non_MT_gene_average_expression.csv'))
478 |
479 | pheatmap(t(gene_to_heatmap),
480 | cluster_rows = FALSE,
481 | cluster_cols = FALSE,
482 | border_color = 'white',
483 | color = colorRampPalette(viridis(9))(100),
484 | cellwidth = 15,
485 | cellheight = 15)
486 | ```
487 |
488 | ### non-MT genes highly expressed in C4 (MHC I class genes)
489 | ```{r fig.height = 4, fig.width = 6, fig.align = 'center'}
490 | p <- VlnPlot(mdm, features = c('B2M', 'HLA-DRA', 'CD74', 'CTSS'),
491 | pt.size = 0, cols = c('#3B82F6', '#EF4444', '#C798EE', '#EAB308', '#F97316', '#854D0E'))
492 | p
493 | ```
494 |
495 | ### MDM/TMDM subclusters analysis using Seurat
496 | ```{r fig.height = 4, fig.width = 10, fig.align = 'center'}
497 | p1 <- ggplot() +
498 | geom_point(mdm_meta_new, mapping = aes(tsne1,tsne2,color = seurat_clusters), size = 3) +
499 | scale_color_manual(values = c('#EAB308', '#EF4444', '#3B82F6', '#C798EE', '#F97316', '#854D0E')) +
500 | theme_classic() +
501 | ggtitle('MDM/TMDM subclusters (Seurat)') +
502 | theme(plot.title = element_text(hjust = 0.5)) +
503 | theme(legend.title = element_blank())
504 |
505 | p2 <- VlnPlot(mdm, features = c('B2M', 'HLA-DRA', 'CD74', 'CTSS'), group.by = 'seurat_clusters', pt.size=0, cols = c('#EAB308', '#EF4444', '#3B82F6', '#C798EE', '#F97316', '#854D0E'))
506 |
507 | cowplot::plot_grid(p1, p2)
508 |
509 | ```
510 |
--------------------------------------------------------------------------------
/AnalysisPaper/output/figure2/DEGs_starmap.csv:
--------------------------------------------------------------------------------
1 | "","p_val","avg_log2FC","pct.1","pct.2","p_val_adj","cluster","gene"
2 | "Pcp4",5.52994783265023e-45,2.14650426368579,0.601,0.172,5.64054678930324e-42,"L6","Pcp4"
3 | "X3110035E14Rik",4.01884444373145e-42,1.99229587187926,0.695,0.291,4.09922133260608e-39,"L6","X3110035E14Rik"
4 | "Rprm",3.80508133010825e-21,1.38335707588428,0.646,0.364,3.88118295671041e-18,"L6","Rprm"
5 | "Tle4",9.76359623219227e-19,1.41189787161448,0.525,0.249,9.95886815683612e-16,"L6","Tle4"
6 | "Hpcal4",1.26760659436933e-18,0.717287724339745,0.928,0.736,1.29295872625671e-15,"L6","Hpcal4"
7 | "Arhgap25",2.03071679283173e-16,1.32215638665533,0.422,0.175,2.07133112868836e-13,"L6","Arhgap25"
8 | "Nptx1",3.02285737222327e-16,1.01613067268938,0.691,0.438,3.08331451966773e-13,"L6","Nptx1"
9 | "Ogfrl1",6.30335355817849e-14,0.929101107838621,0.637,0.387,6.42942062934206e-11,"L6","Ogfrl1"
10 | "Garnl3",2.5267891716968e-13,1.46823669830471,0.368,0.17,2.57732495513073e-10,"L6","Garnl3"
11 | "Arc",5.24910445857555e-13,0.938368694033685,0.753,0.574,5.35408654774706e-10,"L6","Arc"
12 | "Slc17a7",9.33369228767695e-12,0.640045149092102,0.839,0.672,9.52036613343049e-09,"L6","Slc17a7"
13 | "Col6a1",1.34832934315239e-11,1.43511676889979,0.341,0.159,1.37529593001543e-08,"L6","Col6a1"
14 | "Pcsk2",1.68230622939461e-11,0.634622280520908,0.812,0.603,1.7159523539825e-08,"L6","Pcsk2"
15 | "Pgm2l1",1.71995381460967e-11,0.632196090642059,0.834,0.647,1.75435289090187e-08,"L6","Pgm2l1"
16 | "Syn1",1.68039771849225e-10,0.666961869836484,0.74,0.568,1.7140056728621e-07,"L6","Syn1"
17 | "Ptk2",2.80486182555293e-09,0.937789176454751,0.448,0.257,2.86095906206399e-06,"L6","Ptk2"
18 | "Klf10",2.85192808382252e-09,0.922365890234871,0.475,0.294,2.90896664549897e-06,"L6","Klf10"
19 | "Arx",3.00366551661635e-09,0.578768261017132,0.776,0.585,3.06373882694868e-06,"L6","Arx"
20 | "Rasgrp1",3.1776179790911e-09,0.770750463889819,0.471,0.267,3.24117033867292e-06,"L6","Rasgrp1"
21 | "Nrp1",5.79254293303199e-09,1.07589974892201,0.274,0.123,5.90839379169263e-06,"L6","Nrp1"
22 | "Snx10",3.07952413188563e-08,0.555726175391807,0.659,0.449,3.14111461452334e-05,"L6","Snx10"
23 | "Cdh18",1.44025276618245e-07,0.994511489935334,0.238,0.106,0.00014690578215061,"L6","Cdh18"
24 | "X1110008P14Rik",1.48387553760045e-07,0.936185225805391,0.408,0.25,0.000151355304835246,"L6","X1110008P14Rik"
25 | "Plcxd3",2.85791361664326e-07,0.987137071844842,0.354,0.2,0.000291507188897612,"L6","Plcxd3"
26 | "Pdlim1",3.49683263388431e-07,1.11310764342433,0.188,0.076,0.000356676928656199,"L6","Pdlim1"
27 | "Fxyd7",3.77057349535427e-07,0.540734574028797,0.691,0.51,0.000384598496526135,"L6","Fxyd7"
28 | "St3gal5",9.810565435207e-07,0.56119788426824,0.65,0.493,0.00100067767439111,"L6","St3gal5"
29 | "Anapc13",1.2468493549096e-06,0.832238722199556,0.395,0.244,0.00127178634200779,"L6","Anapc13"
30 | "Rab26",2.03863279437458e-06,1.08226489770229,0.278,0.155,0.00207940545026207,"L6","Rab26"
31 | "Slc24a2",2.99283467895756e-06,0.54374838398548,0.543,0.387,0.00305269137253671,"L6","Slc24a2"
32 | "Homer1",3.25998016366246e-06,0.676263923446097,0.525,0.36,0.00332517976693571,"L6","Homer1"
33 | "Prkcg",8.39658181897297e-06,0.839148815086928,0.453,0.31,0.00856451345535243,"L6","Prkcg"
34 | "Efr3a",9.34775982027421e-06,0.620615662585939,0.475,0.331,0.00953471501667969,"L6","Efr3a"
35 | "Slc6a15",1.2327177432897e-05,0.596197445876438,0.466,0.315,0.012573720981555,"L6","Slc6a15"
36 | "X1700019D03Rik",2.35699978231705e-05,0.754883195165629,0.336,0.21,0.0240413977796339,"L6","X1700019D03Rik"
37 | "B3galt2",3.78852929036737e-05,0.914312636657826,0.26,0.154,0.0386429987617472,"L6","B3galt2"
38 | "Itm2c",4.6568506095821e-05,0.53073860520468,0.552,0.434,0.0474998762177374,"L6","Itm2c"
39 | "Gria3",0.000105689728680921,0.533071820105523,0.417,0.286,0.107803523254539,"L6","Gria3"
40 | "Pitpnc1",0.000113740426572601,0.503216410606073,0.341,0.214,0.116015235104053,"L6","Pitpnc1"
41 | "Stx1a",0.000121203590704647,0.602892453018783,0.359,0.236,0.12362766251874,"L6","Stx1a"
42 | "Ipcef1",0.000274614470795035,0.713712823938276,0.202,0.112,0.280106760210936,"L6","Ipcef1"
43 | "Slc5a7",0.000413472190189203,0.734668936645479,0.215,0.126,0.421741633992987,"L6","Slc5a7"
44 | "Syt6",0.000492628935010536,0.636619314346107,0.22,0.129,0.502481513710746,"L6","Syt6"
45 | "Ano3",0.000505046325819418,0.62834110694795,0.341,0.239,0.515147252335806,"L6","Ano3"
46 | "Gpr22",0.000551742062243723,0.56825842091206,0.318,0.216,0.562776903488597,"L6","Gpr22"
47 | "Nfia",0.000567165778978726,0.78746456448652,0.184,0.103,0.578509094558301,"L6","Nfia"
48 | "Tbr1",0.00107870041726061,0.67789846002236,0.296,0.203,1,"L6","Tbr1"
49 | "Obox3",0.00114014300069927,0.527086991842171,0.22,0.134,1,"L6","Obox3"
50 | "Idi1",0.00131945900486207,0.618532821972636,0.26,0.167,1,"L6","Idi1"
51 | "Npas4",0.00172380252273486,0.643812408640338,0.287,0.194,1,"L6","Npas4"
52 | "Mmp16",0.00225781853461978,0.662515738626931,0.283,0.2,1,"L6","Mmp16"
53 | "Ctxn3",0.0030870854586583,0.604855223724219,0.229,0.147,1,"L6","Ctxn3"
54 | "Cpne5",0.00565283875270732,0.521274481257476,0.309,0.227,1,"L6","Cpne5"
55 | "Sema3e",0.00576141333421758,0.605043697919634,0.157,0.095,1,"L6","Sema3e"
56 | "Lmo3",0.00618820693736147,0.519275898203543,0.309,0.224,1,"L6","Lmo3"
57 | "Pcdha5",0.00665565532364777,0.608560936580506,0.197,0.133,1,"L6","Pcdha5"
58 | "C730002L08Rik",0.00695294325652162,0.549213967101861,0.175,0.11,1,"L6","C730002L08Rik"
59 | "Efhd2",0.00925386620563434,0.570423288215215,0.242,0.171,1,"L6","Efhd2"
60 | "Nrsn1",7.23906161911071e-44,1.5741536073085,0.845,0.501,7.38384285149292e-41,"L4","Nrsn1"
61 | "Egr1",3.79101225916544e-29,1.41655810728683,0.763,0.455,3.86683250434874e-26,"L4","Egr1"
62 | "Camk2n1",1.28491966384878e-28,0.858983303373438,0.983,0.866,1.31061805712575e-25,"L4","Camk2n1"
63 | "Zmat4",4.38045134032699e-28,1.63294138245761,0.539,0.209,4.46806036713353e-25,"L4","Zmat4"
64 | "Nrep",9.42893292377221e-27,1.50071100124534,0.629,0.312,9.61751158224765e-24,"L4","Nrep"
65 | "Whrn",5.86551694734778e-17,1.37193715632531,0.478,0.227,5.98282728629473e-14,"L4","Whrn"
66 | "Arc1",2.15970340137585e-13,0.63734100855105,0.78,0.566,2.20289746940336e-10,"L4","Arc"
67 | "Mef2c",2.31932305330235e-10,0.821222643919695,0.565,0.374,2.3657095143684e-07,"L4","Mef2c"
68 | "Rorb",4.6325371455539e-10,1.13933628675489,0.358,0.183,4.72518788846497e-07,"L4","Rorb"
69 | "Nrn1",7.73119747920001e-10,0.727398775226397,0.586,0.385,7.88582142878401e-07,"L4","Nrn1"
70 | "Pamr1",9.2201287003694e-10,1.21277954965985,0.194,0.067,9.40453127437679e-07,"L4","Pamr1"
71 | "Cux2",1.18749980703972e-08,0.742381384763552,0.5,0.308,1.21124980318052e-05,"L4","Cux2"
72 | "Nell1",2.05438835008246e-08,0.93158053724283,0.552,0.388,2.09547611708411e-05,"L4","Nell1"
73 | "Snca",7.64163613941064e-08,0.61445017167414,0.694,0.555,7.79446886219885e-05,"L4","Snca"
74 | "Nudt4",8.11865848700165e-08,0.745260213807436,0.44,0.269,8.28103165674168e-05,"L4","Nudt4"
75 | "Epha4",9.40472428463228e-08,0.81149372803082,0.487,0.33,9.59281877032493e-05,"L4","Epha4"
76 | "Egr3",2.10853483874152e-07,0.686254813851037,0.565,0.396,0.000215070553551635,"L4","Egr3"
77 | "Ralyl",2.83345866174247e-07,0.671073314641947,0.5,0.348,0.000289012783497732,"L4","Ralyl"
78 | "Btbd3",4.59918275675397e-07,0.891226896514263,0.388,0.244,0.000469116641188905,"L4","Btbd3"
79 | "Osbpl1a",4.70814923537492e-07,0.781124551622579,0.384,0.238,0.000480231222008242,"L4","Osbpl1a"
80 | "Arpp21",8.47634052316421e-07,0.700300624929771,0.642,0.529,0.00086458673336275,"L4","Arpp21"
81 | "X2900055J20Rik",9.13626416089784e-07,0.763543290505279,0.453,0.302,0.00093189894441158,"L4","X2900055J20Rik"
82 | "Plcxd2",1.23530726556292e-06,1.05344946197166,0.19,0.084,0.00126001341087418,"L4","Plcxd2"
83 | "Satb2",1.75471539640686e-06,0.738125687267868,0.491,0.339,0.00178980970433499,"L4","Satb2"
84 | "Grik1",7.60301404609683e-06,1.01866392286873,0.237,0.124,0.00775507432701877,"L4","Grik1"
85 | "Nr4a1",8.06710506740604e-06,0.650611921038291,0.496,0.348,0.00822844716875416,"L4","Nr4a1"
86 | "Cpne9",1.68912386437158e-05,0.983244830505565,0.25,0.144,0.0172290634165901,"L4","Cpne9"
87 | "Foxp1",4.62596562247274e-05,0.784650175799453,0.28,0.165,0.047184849349222,"L4","Foxp1"
88 | "Spock3",5.00162465789816e-05,0.84420553134671,0.216,0.117,0.0510165715105612,"L4","Spock3"
89 | "Gfra2",8.80374892725387e-05,0.726605862558507,0.405,0.297,0.0897982390579895,"L4","Gfra2"
90 | "Egr2",9.57025671190647e-05,0.662484941475747,0.31,0.197,0.097616618461446,"L4","Egr2"
91 | "Vgf",0.000137765381294501,0.557640618124698,0.47,0.344,0.140520688920391,"L4","Vgf"
92 | "Fam19a2",0.000194078982778318,0.638680963937566,0.353,0.235,0.197960562433885,"L4","Fam19a2"
93 | "Rit2",0.000264442979414777,0.598366508504173,0.384,0.279,0.269731839003072,"L4","Rit2"
94 | "Syndig1",0.000344745093464633,0.596899732604372,0.284,0.182,0.351639995333926,"L4","Syndig1"
95 | "S100a10",0.0004371251574989,0.627061001736399,0.267,0.175,0.445867660648878,"L4","S100a10"
96 | "Hnrnph2",0.000677447555387016,0.532987048269152,0.392,0.287,0.690996506494757,"L4","Hnrnph2"
97 | "Nos1",0.000765474268739021,0.667445133473259,0.207,0.124,0.780783754113802,"L4","Nos1"
98 | "Dusp14",0.000811181823189736,0.711602550152013,0.25,0.165,0.827405459653531,"L4","Dusp14"
99 | "Hmgcr",0.0016904440648399,0.521995905746759,0.366,0.27,1,"L4","Hmgcr"
100 | "Cbln4",0.00178968993807231,0.66977878962358,0.177,0.105,1,"L4","Cbln4"
101 | "Cnih3",0.00182574750106368,0.514114838915157,0.345,0.253,1,"L4","Cnih3"
102 | "Rgs4",0.00201388656734114,0.513524893777207,0.384,0.288,1,"L4","Rgs4"
103 | "Chrm2",0.0029992796940059,0.513149812906267,0.267,0.181,1,"L4","Chrm2"
104 | "Fbxo11",0.00358487644903016,0.581720980312428,0.233,0.156,1,"L4","Fbxo11"
105 | "Lrrc4c",0.00463376447297917,0.649245341830728,0.237,0.166,1,"L4","Lrrc4c"
106 | "Pcdhb7",0.00543657920658995,0.658763268043111,0.112,0.061,1,"L4","Pcdhb7"
107 | "Scml4",0.00619755996308728,0.556724706765482,0.151,0.091,1,"L4","Scml4"
108 | "Camk4",0.0091161877797647,0.587944521112682,0.172,0.113,1,"L4","Camk4"
109 | "Lamp5",3.66980779111143e-49,1.91552193381508,0.744,0.308,3.74320394693366e-46,"L2/3","Lamp5"
110 | "Camk2n11",1.44411378662633e-36,0.87104473422646,0.981,0.862,1.47299606235885e-33,"L2/3","Camk2n1"
111 | "Cux21",5.06537141968682e-29,1.3226734710255,0.626,0.267,5.16667884808055e-26,"L2/3","Cux2"
112 | "Cpne51",2.16578701835151e-18,1.09612258963261,0.454,0.183,2.20910275871855e-15,"L2/3","Cpne5"
113 | "Nrgn",8.92359352276684e-18,0.707295492709649,0.897,0.697,9.10206539322218e-15,"L2/3","Nrgn"
114 | "Enc1",1.81427244126243e-16,0.83875109615125,0.618,0.334,1.85055789008768e-13,"L2/3","Enc1"
115 | "Calb1",3.41900215267736e-15,1.28716048359496,0.317,0.116,3.48738219573091e-12,"L2/3","Calb1"
116 | "Cbln2",2.53003186889626e-14,1.03074735225577,0.515,0.278,2.58063250627418e-11,"L2/3","Cbln2"
117 | "Gucy1b3",1.32118763191791e-13,0.830553661520547,0.607,0.364,1.34761138455627e-10,"L2/3","Gucy1b3"
118 | "Ddit4l",1.61490350916266e-13,1.13877873290154,0.244,0.076,1.64720157934591e-10,"L2/3","Ddit4l"
119 | "Pcsk21",9.27286108636596e-13,0.715928066135392,0.782,0.602,9.45831830809328e-10,"L2/3","Pcsk2"
120 | "Nr4a11",1.15430779019837e-10,0.729558199195297,0.546,0.329,1.17739394600234e-07,"L2/3","Nr4a1"
121 | "X2900055J20Rik1",1.30726611299039e-10,0.796159130339213,0.492,0.286,1.33341143525019e-07,"L2/3","X2900055J20Rik"
122 | "Camk2a",1.80713086129622e-10,0.558177675204675,0.786,0.543,1.84327347852215e-07,"L2/3","Camk2a"
123 | "Lrrtm4",2.5279410797104e-10,0.883639025025325,0.321,0.144,2.57849990130461e-07,"L2/3","Lrrtm4"
124 | "Cenpw",1.02917131199735e-09,0.999767868855619,0.317,0.153,1.0497547382373e-06,"L2/3","Cenpw"
125 | "Efna5",5.9088822010461e-09,0.901751044589718,0.359,0.186,6.02705984506702e-06,"L2/3","Efna5"
126 | "Trp53i11",2.33714644768813e-08,0.846937016759762,0.344,0.184,2.3838893766419e-05,"L2/3","Trp53i11"
127 | "Acvr1c",2.93653694330845e-08,0.719042401635915,0.355,0.192,2.99526768217462e-05,"L2/3","Acvr1c"
128 | "Atp2b4",8.24853388349099e-08,0.89709205742434,0.275,0.137,8.41350456116081e-05,"L2/3","Atp2b4"
129 | "Rbfox3",1.2758533016473e-07,0.750286245559642,0.45,0.281,0.000130137036768024,"L2/3","Rbfox3"
130 | "Chodl",1.53509446909417e-07,0.862885443834019,0.248,0.116,0.000156579635847605,"L2/3","Chodl"
131 | "Car10",1.67522080893593e-07,0.793210172078162,0.298,0.152,0.000170872522511465,"L2/3","Car10"
132 | "Nell2",1.77745919493807e-07,0.861392781632943,0.271,0.137,0.000181300837883683,"L2/3","Nell2"
133 | "Nectin3",1.81757126127172e-07,0.710117642582952,0.401,0.229,0.000185392268649716,"L2/3","Nectin3"
134 | "Rsph9",2.69257418555156e-07,0.927044782172142,0.168,0.065,0.000274642566926259,"L2/3","Rsph9"
135 | "Nrn11",3.05824356038805e-07,0.547187924576972,0.565,0.384,0.000311940843159581,"L2/3","Nrn1"
136 | "X6330403K07Rik",3.60096503051553e-07,0.686224646211152,0.279,0.139,0.000367298433112584,"L2/3","X6330403K07Rik"
137 | "Fam19a21",4.11014422625529e-07,0.586305436936738,0.389,0.221,0.00041923471107804,"L2/3","Fam19a2"
138 | "Lrrc4c1",4.944891738196e-07,0.716309517281832,0.29,0.149,0.000504378957295992,"L2/3","Lrrc4c"
139 | "Cd34",6.69335728682245e-07,0.658041391029057,0.321,0.175,0.00068272244325589,"L2/3","Cd34"
140 | "Ptpn2",8.14516106951469e-07,0.622756221051355,0.252,0.122,0.000830806429090499,"L2/3","Ptpn2"
141 | "Ptgs2",9.79933995863862e-07,0.972216029464756,0.225,0.105,0.000999532675781139,"L2/3","Ptgs2"
142 | "Fosl2",1.3744752940499e-06,0.747469393479483,0.332,0.19,0.00140196479993089,"L2/3","Fosl2"
143 | "Ptchd2",1.9194060951934e-06,0.710958940337194,0.225,0.111,0.00195779421709727,"L2/3","Ptchd2"
144 | "Ptk2b",2.14114612242775e-06,0.634772288334147,0.412,0.252,0.0021839690448763,"L2/3","Ptk2b"
145 | "X1700086L19Rik",2.21932885429204e-06,0.685815270666915,0.328,0.189,0.00226371543137788,"L2/3","X1700086L19Rik"
146 | "Arpp211",2.59562312679982e-06,0.509673637076189,0.66,0.521,0.00264753558933581,"L2/3","Arpp21"
147 | "Ralyl1",3.47076852394955e-06,0.573639326881924,0.508,0.341,0.00354018389442854,"L2/3","Ralyl"
148 | "Mef2c1",3.51288203834102e-06,0.512058701366271,0.542,0.375,0.00358313967910784,"L2/3","Mef2c"
149 | "B230216N24Rik",3.51775009115177e-06,0.719950142826318,0.221,0.108,0.0035881050929748,"L2/3","B230216N24Rik"
150 | "Gria31",3.84459195271401e-06,0.524123214714924,0.435,0.275,0.00392148379176829,"L2/3","Gria3"
151 | "Pcdhb19",4.45545801912821e-06,0.777926202128252,0.198,0.093,0.00454456717951077,"L2/3","Pcdhb19"
152 | "Pdlim3",4.50069319971527e-06,0.701152685855864,0.26,0.139,0.00459070706370958,"L2/3","Pdlim3"
153 | "Cyb5r1",4.56679478380407e-06,0.582783480254336,0.244,0.126,0.00465813067948015,"L2/3","Cyb5r1"
154 | "Glt8d2",4.79931327389878e-06,0.7170625209065,0.282,0.152,0.00489529953937675,"L2/3","Glt8d2"
155 | "Ptn",4.84979464424312e-06,0.519538015166196,0.378,0.219,0.00494679053712798,"L2/3","Ptn"
156 | "Arpp19",5.03947166512861e-06,0.51857480800012,0.519,0.357,0.00514026109843118,"L2/3","Arpp19"
157 | "Egr4",5.69820679624407e-06,0.720357569678328,0.24,0.125,0.00581217093216895,"L2/3","Egr4"
158 | "Wt1",6.23193753296308e-06,0.713705395975799,0.183,0.084,0.00635657628362235,"L2/3","Wt1"
159 | "Pdzrn3",7.2447410916497e-06,0.665707393094456,0.385,0.241,0.0073896359134827,"L2/3","Pdzrn3"
160 | "Skil",8.25876704905922e-06,0.550144210982253,0.298,0.167,0.0084239423900404,"L2/3","Skil"
161 | "Vip",9.5557040520132e-06,1.47967402193907,0.214,0.109,0.00974681813305346,"L2/3","Vip"
162 | "Herc3",1.36337419595036e-05,0.614905008635465,0.302,0.172,0.0139064167986936,"L2/3","Herc3"
163 | "Ttyh1",1.6240070197839e-05,0.651699088637335,0.382,0.243,0.0165648716017958,"L2/3","Ttyh1"
164 | "Pcdhb2",1.99628286344e-05,0.555915244580013,0.256,0.143,0.020362085207088,"L2/3","Pcdhb2"
165 | "Itm2a",2.29543945411187e-05,0.808307051110131,0.233,0.126,0.0234134824319411,"L2/3","Itm2a"
166 | "Adm",2.61019796877386e-05,0.885045963420287,0.118,0.048,0.0266240192814934,"L2/3","Adm"
167 | "Rasgef1b",2.7565796136891e-05,0.530893571096449,0.244,0.132,0.0281171120596288,"L2/3","Rasgef1b"
168 | "Adk",4.10704780305577e-05,0.736494938833014,0.176,0.087,0.0418918875911689,"L2/3","Adk"
169 | "Rgs41",4.68042469073209e-05,0.564254025933605,0.42,0.275,0.0477403318454673,"L2/3","Rgs4"
170 | "Cacng3",4.75243873399403e-05,0.644704086226482,0.355,0.232,0.0484748750867392,"L2/3","Cacng3"
171 | "Dlx1",5.20571339734539e-05,0.757455366795206,0.164,0.079,0.053098276652923,"L2/3","Dlx1"
172 | "Gpr88",9.83241402715632e-05,0.621038922295348,0.279,0.169,0.100290623076994,"L2/3","Gpr88"
173 | "Pcdhb9",0.000109120554995124,0.532100979552728,0.256,0.148,0.111302966095027,"L2/3","Pcdhb9"
174 | "Pcdhb11",0.000118667772873231,0.581169370481358,0.141,0.066,0.121041128330695,"L2/3","Pcdhb11"
175 | "Pcdhga8",0.000129853884124749,0.519033844272103,0.218,0.12,0.132450961807244,"L2/3","Pcdhga8"
176 | "Gpr151",0.000134181905403226,0.536002186805389,0.237,0.135,0.136865543511291,"L2/3","Gpr151"
177 | "Nptx2",0.000158602933300447,0.51797823872194,0.286,0.177,0.161774991966456,"L2/3","Nptx2"
178 | "Penk",0.000166091466861298,0.696394276589771,0.233,0.139,0.169413296198524,"L2/3","Penk"
179 | "Dcn",0.000176906706238821,0.605741286436307,0.134,0.062,0.180444840363598,"L2/3","Dcn"
180 | "Gm765",0.000231591566981269,0.793772756512939,0.29,0.186,0.236223398320894,"L2/3","Gm765"
181 | "Lin7b",0.000236371102995397,0.541122669822179,0.286,0.18,0.241098525055305,"L2/3","Lin7b"
182 | "Btbd10",0.000274578966976598,0.618655712968628,0.248,0.15,0.28007054631613,"L2/3","Btbd10"
183 | "Trim32",0.000298401757342806,0.507977152364097,0.366,0.249,0.304369792489662,"L2/3","Trim32"
184 | "Cited1",0.000345126744720481,0.545972202996576,0.149,0.075,0.352029279614891,"L2/3","Cited1"
185 | "Pcdha51",0.000359196303501419,0.510490026531889,0.218,0.125,0.366380229571448,"L2/3","Pcdha5"
186 | "Cck",0.000390776296517091,0.647476269938392,0.145,0.074,0.398591822447433,"L2/3","Cck"
187 | "Bcar3",0.00043066687308687,0.501751081583371,0.294,0.188,0.439280210548608,"L2/3","Bcar3"
188 | "Pcdhga7",0.000517547403219853,0.529543246258775,0.282,0.179,0.52789835128425,"L2/3","Pcdhga7"
189 | "Tmx1",0.000537195194089707,0.549789999715377,0.237,0.144,0.547939097971501,"L2/3","Tmx1"
190 | "Htr3a",0.0005530744733133,0.744872561034185,0.141,0.072,0.564135962779566,"L2/3","Htr3a"
191 | "Flpo",0.000584685161523634,0.553905335961613,0.145,0.074,0.596378864754106,"L2/3","Flpo"
192 | "Chrm21",0.000639873867750676,0.598510964009418,0.271,0.177,0.652671345105689,"L2/3","Chrm2"
193 | "Pcdhb17",0.000742055368751118,0.53815878984759,0.218,0.129,0.75689647612614,"L2/3","Pcdhb17"
194 | "Wfs1",0.000762388767740869,0.814841188930781,0.134,0.069,0.777636543095686,"L2/3","Wfs1"
195 | "Rgs8",0.00107943442052924,0.710316721058641,0.149,0.08,1,"L2/3","Rgs8"
196 | "Skap1",0.0011010687552351,0.582468514757153,0.282,0.187,1,"L2/3","Skap1"
197 | "Cbln41",0.00132499183169679,0.556977087754115,0.176,0.103,1,"L2/3","Cbln4"
198 | "Cd7",0.00151173510809438,0.654895518730535,0.172,0.102,1,"L2/3","Cd7"
199 | "Tmem215",0.001853332475003,0.519563515261213,0.198,0.122,1,"L2/3","Tmem215"
200 | "Cdk4",0.00229795516386357,0.50961903130755,0.141,0.078,1,"L2/3","Cdk4"
201 | "Ephx2",0.00294704088032987,0.513215611769445,0.172,0.103,1,"L2/3","Ephx2"
202 | "Thsd7a",0.00348807373082877,0.559983429558063,0.179,0.112,1,"L2/3","Thsd7a"
203 | "St3gal6",0.00360156812147586,0.550921900675123,0.118,0.063,1,"L2/3","St3gal6"
204 | "Smim8",0.0038728787715026,0.517842786311477,0.233,0.154,1,"L2/3","Smim8"
205 | "Crip2",0.00409499858185449,0.521480897254056,0.374,0.28,1,"L2/3","Crip2"
206 | "Mas1",0.00668626525260274,0.666878913872491,0.103,0.055,1,"L2/3","Mas1"
207 | "Dhrs3",0.00766310763187726,0.615109421178318,0.176,0.113,1,"L2/3","Dhrs3"
208 | "Foxp2",0.00852955197250509,0.545543019681397,0.111,0.062,1,"L2/3","Foxp2"
209 | "Camk2a1",9.81520121587716e-09,0.965872020354466,0.757,0.579,1.00115052401947e-05,"L1","Camk2a"
210 | "Fosb",3.09646910917638e-08,1.00058689941114,0.703,0.502,3.15839849135991e-05,"L1","Fosb"
211 | "Hpcal41",4.73709023720236e-08,0.895298670034147,0.874,0.761,4.8318320419464e-05,"L1","Hpcal4"
212 | "Camk2n12",5.97102985036036e-08,0.527531892635579,0.955,0.881,6.09045044736757e-05,"L1","Camk2n1"
213 | "Pcdhac2",1.52251038662404e-06,1.4076940892422,0.18,0.059,0.00155296059435652,"L1","Pcdhac2"
214 | "Cux22",1.36043963712507e-05,0.892146081052945,0.523,0.327,0.0138764842986757,"L1","Cux2"
215 | "Btbd11",2.37855620735035e-05,0.973043003195559,0.532,0.359,0.0242612733149736,"L1","Btbd11"
216 | "Bsg",6.53112507254391e-05,0.659848422286122,0.559,0.421,0.0666174757399479,"L1","Bsg"
217 | "Mapk3",9.7276951652946e-05,0.93761221444135,0.243,0.115,0.099222490686005,"L1","Mapk3"
218 | "Tmem176a",0.000110642398613413,1.11766297652847,0.297,0.158,0.112855246585681,"L1","Tmem176a"
219 | "Itm2a1",0.000251929731995325,0.919005146927914,0.261,0.138,0.256968326635232,"L1","Itm2a"
220 | "Pfn1",0.000263169403072857,1.08204983795012,0.252,0.134,0.268432791134314,"L1","Pfn1"
221 | "Sdc4",0.000268061329872921,0.745242331588592,0.604,0.465,0.27342255647038,"L1","Sdc4"
222 | "Wfs11",0.00029631495891192,0.98928383136213,0.171,0.074,0.302241258090158,"L1","Wfs1"
223 | "Glul",0.000298060326625853,0.503452757975648,0.892,0.901,0.30402153315837,"L1","Glul"
224 | "B2m",0.00040416362644854,0.716269682911794,0.432,0.278,0.412246898977511,"L1","B2m"
225 | "Sgk1",0.000533049496082616,1.06983510053123,0.324,0.203,0.543710486004268,"L1","Sgk1"
226 | "Nell21",0.000858621097127548,0.954794161389083,0.27,0.155,0.875793519070099,"L1","Nell2"
227 | "Pcdh8",0.00125571201654819,0.62195574382669,0.378,0.244,1,"L1","Pcdh8"
228 | "Myo5b",0.00179718935535024,0.90070579859649,0.162,0.078,1,"L1","Myo5b"
229 | "Abhd3",0.00182577127041894,0.905809253477873,0.243,0.142,1,"L1","Abhd3"
230 | "Slc38a3",0.00195386716508055,0.714677449834267,0.396,0.265,1,"L1","Slc38a3"
231 | "Gpm6b",0.00196566010503703,0.580869578027183,0.694,0.577,1,"L1","Gpm6b"
232 | "Aldh1l1",0.00210298085461146,1.12743497081162,0.207,0.115,1,"L1","Aldh1l1"
233 | "Nat8f1",0.00231197303168397,1.05302218895438,0.27,0.162,1,"L1","Nat8f1"
234 | "Inhba",0.00271758551204047,0.815773177187916,0.225,0.125,1,"L1","Inhba"
235 | "C1ql3",0.0027851153657435,0.639644212840066,0.378,0.253,1,"L1","C1ql3"
236 | "Nr2f2",0.00338392501263764,0.791983466933333,0.216,0.12,1,"L1","Nr2f2"
237 | "Sepp1",0.00429975152166601,0.821260994073221,0.468,0.376,1,"L1","Sepp1"
238 | "Prc1",0.00441091670242078,0.696924925762886,0.279,0.17,1,"L1","Prc1"
239 | "Slc1a3",0.004660436064834,0.955980102905765,0.586,0.507,1,"L1","Slc1a3"
240 | "Adarb2",0.00565075488436639,1.01822598311269,0.234,0.146,1,"L1","Adarb2"
241 | "Stx12",0.00577312232730529,0.768215659866426,0.171,0.09,1,"L1","Stx12"
242 | "Dgkb",0.00578102426201576,1.01262612333672,0.234,0.142,1,"L1","Dgkb"
243 | "Sparc",0.00643701155910009,0.716197392038294,0.261,0.162,1,"L1","Sparc"
244 | "Znhit3",0.00668606188525176,0.913540870272503,0.162,0.088,1,"L1","Znhit3"
245 | "S100a16",0.00746874317921263,0.740087287671085,0.342,0.246,1,"L1","S100a16"
246 | "Rgs81",0.00766765840187434,0.843395545842034,0.162,0.089,1,"L1","Rgs8"
247 | "Tmbim6",0.00966760815941394,0.602362481921111,0.432,0.323,1,"L1","Tmbim6"
248 | "Atp1b2",0.00973556273468001,0.611522750165142,0.36,0.256,1,"L1","Atp1b2"
249 | "Hlf",0.00974488018813224,0.502057754224952,0.91,0.904,1,"L1","Hlf"
250 | "Coro6",0.00982092969122705,0.550316648499994,0.252,0.157,1,"L1","Coro6"
251 | "Mbp",1.86447304010502e-92,3.67951761077413,0.987,0.373,1.90176250090712e-89,"CC","Mbp"
252 | "Mobp",1.75684021493073e-86,3.41546373895894,0.974,0.369,1.79197701922934e-83,"CC","Mobp"
253 | "Plp1",3.28010186457621e-71,3.64234712853681,0.922,0.349,3.34570390186773e-68,"CC","Plp1"
254 | "Gatm",1.01275762917043e-40,2.42423248169432,0.708,0.262,1.03301278175384e-37,"CC","Gatm"
255 | "Trf",4.71802980866908e-40,2.51821910142948,0.623,0.186,4.81239040484246e-37,"CC","Trf"
256 | "Mcts1",3.80353612677908e-33,2.65096869937628,0.539,0.171,3.87960684931466e-30,"CC","Mcts1"
257 | "Cav1",1.60843458683635e-31,2.10117169266395,0.584,0.197,1.64060327857307e-28,"CC","Cav1"
258 | "Mal",2.65397883065207e-30,2.67887844847499,0.526,0.174,2.70705840726511e-27,"CC","Mal"
259 | "Sept4",3.05798688879303e-27,2.15994723459124,0.656,0.323,3.11914662656889e-24,"CC","Sept4"
260 | "Plekhb1",1.10738532440604e-26,1.38534284276648,0.851,0.68,1.12953303089416e-23,"CC","Plekhb1"
261 | "Aprt",3.99024910570115e-26,2.5024279693756,0.396,0.104,4.07005408781518e-23,"CC","Aprt"
262 | "Sox2ot",1.51533081519137e-23,2.34635943658809,0.416,0.127,1.5456374314952e-20,"CC","Sox2ot"
263 | "Bcl6",3.09363799304412e-23,0.981970164839274,0.955,0.883,3.155510752905e-20,"CC","Bcl6"
264 | "Apod",3.57881831934528e-23,1.99036442053318,0.656,0.358,3.65039468573219e-20,"CC","Apod"
265 | "Qk",4.18121469900398e-23,1.43672435176165,0.812,0.642,4.26483899298406e-20,"CC","Qk"
266 | "Car2",6.05110789178984e-22,1.92304273899421,0.494,0.184,6.17213004962564e-19,"CC","Car2"
267 | "Kif5a",6.66214851399637e-21,1.11555120088842,0.883,0.764,6.7953914842763e-18,"CC","Kif5a"
268 | "Teddm3",5.92982042705849e-20,2.29315108123936,0.403,0.136,6.04841683559966e-17,"CC","Teddm3"
269 | "Esd",2.21712870136804e-18,1.85010794202163,0.494,0.22,2.2614712753954e-15,"CC","Esd"
270 | "Ptgds",5.63068836985463e-17,0.696032858370176,0.649,0.361,5.74330213725173e-14,"CC","Ptgds"
271 | "Gfap",2.71797939525523e-16,1.8973579384897,0.487,0.226,2.77233898316033e-13,"CC","Gfap"
272 | "Gstm6",1.46325530049324e-15,1.86176048592186,0.403,0.162,1.49252040650311e-12,"CC","Gstm6"
273 | "Lcat",1.60273465915533e-14,2.07230657848721,0.39,0.166,1.63478935233843e-11,"CC","Lcat"
274 | "Hlf1",5.19482007736139e-13,0.577063521366935,0.935,0.9,5.29871647890862e-10,"CC","Hlf"
275 | "Cd9",5.42446411708351e-12,1.16292462105661,0.623,0.408,5.53295339942519e-09,"CC","Cd9"
276 | "Gad2",4.33226867213496e-11,1.59674606374523,0.409,0.211,4.41891404557766e-08,"CC","Gad2"
277 | "Cend1",5.94350077437529e-11,0.867931667867409,0.799,0.648,6.06237078986279e-08,"CC","Cend1"
278 | "Rnf13",5.94428580633791e-11,1.34176100910094,0.448,0.243,6.06317152246467e-08,"CC","Rnf13"
279 | "Cryab",4.25380047831565e-10,1.55028408329782,0.461,0.274,4.33887648788196e-07,"CC","Cryab"
280 | "Spon1",1.6209506475699e-09,1.20750853401943,0.526,0.341,1.6533696605213e-06,"CC","Spon1"
281 | "Gsn",2.92329184278261e-09,1.64000653966246,0.37,0.195,2.98175767963827e-06,"CC","Gsn"
282 | "Pllp",4.72536305533494e-09,1.70709127302396,0.273,0.116,4.81987031644164e-06,"CC","Pllp"
283 | "Fam19a1",5.08393804040054e-09,1.46598934426218,0.409,0.242,5.18561680120855e-06,"CC","Fam19a1"
284 | "Igsf3",5.31896997309911e-08,1.10473319829479,0.461,0.292,5.42534937256109e-05,"CC","Igsf3"
285 | "Fosb1",7.13689996850097e-08,0.912610154316035,0.63,0.504,7.27963796787099e-05,"CC","Fosb"
286 | "Hsd3b7",1.19055119940377e-07,1.1456800589579,0.357,0.191,0.000121436222339185,"CC","Hsd3b7"
287 | "Slc32a1",1.5366281436928e-07,1.08200766510419,0.416,0.257,0.000156736070656666,"CC","Slc32a1"
288 | "Ddit3",2.7985335807829e-07,0.996717990885939,0.532,0.385,0.000285450425239856,"CC","Ddit3"
289 | "Adarb21",4.06356635202762e-07,1.14848668126005,0.279,0.136,0.000414483767906817,"CC","Adarb2"
290 | "Pcdhb8",9.25748508578578e-07,1.35459923154992,0.182,0.069,0.000944263478750149,"CC","Pcdhb8"
291 | "Tmeff2",2.17189150013305e-06,1.24056045242691,0.325,0.187,0.00221532933013572,"CC","Tmeff2"
292 | "Hs3st1",3.37745940470364e-06,1.31790064593983,0.422,0.302,0.00344500859279771,"CC","Hs3st1"
293 | "Dusp6",4.21147785526888e-06,0.711859904327854,0.708,0.631,0.00429570741237425,"CC","Dusp6"
294 | "Msmo1",5.04618254540657e-06,0.868490880068891,0.409,0.273,0.0051471061963147,"CC","Msmo1"
295 | "Cnp",9.03137705289469e-06,1.1527177143629,0.318,0.188,0.00921200459395258,"CC","Cnp"
296 | "Enpp2",1.31394477621298e-05,1.08895785264804,0.442,0.317,0.0134022367173724,"CC","Enpp2"
297 | "Mrpl22",2.09255627189844e-05,0.716278452719481,0.643,0.57,0.0213440739733641,"CC","Mrpl22"
298 | "Apoe",2.44670083499305e-05,0.935207830975052,0.617,0.613,0.0249563485169291,"CC","Apoe"
299 | "Mt2",2.65338130432553e-05,1.04020343034375,0.474,0.359,0.0270644893041204,"CC","Mt2"
300 | "Rbm18",3.16857731652534e-05,0.939633242784327,0.442,0.333,0.0323194886285585,"CC","Rbm18"
301 | "Vstm2a",4.26043787645261e-05,1.00329922189629,0.409,0.302,0.0434564663398166,"CC","Vstm2a"
302 | "Pon2",9.27167960658039e-05,0.718751782317697,0.474,0.365,0.09457113198712,"CC","Pon2"
303 | "Sepp11",9.75103050431475e-05,0.774639482974576,0.481,0.37,0.0994605111440105,"CC","Sepp1"
304 | "Ucma",0.000131100056515779,1.1870134062557,0.195,0.1,0.133722057646094,"CC","Ucma"
305 | "Tcerg1l",0.000180391428916735,1.16959131127731,0.351,0.253,0.18399925749507,"CC","Tcerg1l"
306 | "Cmtm5",0.000210017325491012,1.13885656502881,0.299,0.197,0.214217672000833,"CC","Cmtm5"
307 | "Nrsn2",0.000220286765012983,1.02886237090502,0.338,0.236,0.224692500313243,"CC","Nrsn2"
308 | "Psat1",0.000567891155603228,0.602869815830916,0.571,0.482,0.579248978715293,"CC","Psat1"
309 | "Fstl5",0.000851140701058514,1.00656117306921,0.188,0.104,0.868163515079684,"CC","Fstl5"
310 | "Htr5b",0.00106802986152974,1.03286863686677,0.279,0.189,1,"CC","Htr5b"
311 | "Pcdhga3",0.00116796219909119,0.520118761226462,0.649,0.655,1,"CC","Pcdhga3"
312 | "Trap1",0.0011714414124892,1.28812092293134,0.214,0.131,1,"CC","Trap1"
313 | "Dtwd1",0.0011971440362607,0.965129692013645,0.208,0.122,1,"CC","Dtwd1"
314 | "Pdlim11",0.00190455176268907,0.843455236803178,0.162,0.087,1,"CC","Pdlim1"
315 | "Pfkl",0.00202865786452909,0.869858196212576,0.357,0.281,1,"CC","Pfkl"
316 | "Spp1",0.00373085905510645,0.898780831430939,0.143,0.077,1,"CC","Spp1"
317 | "Resp18",0.00545987738733048,1.07862275499959,0.13,0.07,1,"CC","Resp18"
318 | "Coch",0.00591107273465872,0.671481870005505,0.331,0.254,1,"CC","Coch"
319 | "Lhx1",0.00613723026585372,0.626222594670639,0.37,0.3,1,"CC","Lhx1"
320 | "Lman1l",0.00630726126982367,0.598606440671149,0.591,0.568,1,"CC","Lman1l"
321 | "Sst",4.64496101658131e-08,2.76812340579502,0.304,0.1,4.73786023691294e-05,"HPC","Sst"
322 | "Gfap1",3.23877661251999e-06,1.0921160331023,0.478,0.246,0.00330355214477039,"HPC","Gfap"
323 | "Qpct",1.90042130234367e-05,1.29289796394232,0.217,0.073,0.0193842972839055,"HPC","Qpct"
324 | "Gemin7",2.07376939176232e-05,0.97043986953196,0.638,0.428,0.0211524477959756,"HPC","Gemin7"
325 | "Ptprz1",9.36479203190204e-05,1.13820577009249,0.565,0.399,0.0955208787254008,"HPC","Ptprz1"
326 | "Apoe1",0.000252258008727081,0.955618037483084,0.754,0.605,0.257303168901622,"HPC","Apoe"
327 | "Plpp3",0.000329703514279667,0.966425115060226,0.536,0.341,0.33629758456526,"HPC","Plpp3"
328 | "Mt21",0.000355371545493905,1.31131031785294,0.507,0.366,0.362478976403783,"HPC","Mt2"
329 | "Dbi",0.000430150658032958,1.03855439407146,0.551,0.373,0.438753671193617,"HPC","Dbi"
330 | "Ascl1",0.000460300076256422,1.1883199929704,0.232,0.102,0.469506077781551,"HPC","Ascl1"
331 | "Mt1",0.000511081399047552,0.903158545245094,0.696,0.616,0.521303027028503,"HPC","Mt1"
332 | "Tmem179b",0.00213054642633814,0.961644225089181,0.275,0.142,1,"HPC","Tmem179b"
333 | "Twistnb",0.00229167862409836,0.908109509860824,0.304,0.167,1,"HPC","Twistnb"
334 | "Htra1",0.00231142234085296,0.827423780616928,0.522,0.379,1,"HPC","Htra1"
335 | "Snrpb2",0.00256880042543693,1.02108108372555,0.159,0.065,1,"HPC","Snrpb2"
336 | "Slc1a2",0.00265237155825602,0.674589490655206,0.768,0.641,1,"HPC","Slc1a2"
337 | "Tnfrsf12a",0.00367599318866908,1.00216141381185,0.246,0.133,1,"HPC","Tnfrsf12a"
338 | "Dusp61",0.00525356548898912,0.510192840609576,0.739,0.634,1,"HPC","Dusp6"
339 | "Gng7",0.00606502978971731,0.613161011776317,0.29,0.163,1,"HPC","Gng7"
340 | "Mbp1",0.00616502895875102,0.777665668253011,0.565,0.445,1,"HPC","Mbp"
341 | "Gpr37l1",0.00716947296324967,0.634747899302053,0.464,0.325,1,"HPC","Gpr37l1"
342 | "St6galnac5",0.00720363878942158,1.3690414371527,0.391,0.283,1,"HPC","St6galnac5"
343 | "Ythdc1",0.00905594468705341,0.734015464459866,0.493,0.397,1,"HPC","Ythdc1"
344 | "Cplx1",2.89184576174634e-19,1.01040999714847,0.821,0.577,2.94968267698126e-16,"L5","Cplx1"
345 | "Rab3c",7.88616174854388e-19,1.70964840047491,0.5,0.208,8.04388498351476e-16,"L5","Rab3c"
346 | "Pcp41",5.58475931667256e-10,1.06507256587353,0.436,0.224,5.69645450300601e-07,"L5","Pcp4"
347 | "Nefl",2.23439682089166e-08,1.12010175998537,0.372,0.183,2.2790847573095e-05,"L5","Nefl"
348 | "Etv1",1.36619398687931e-07,0.981337318456533,0.321,0.151,0.00013935178666169,"L5","Etv1"
349 | "Fezf2",3.3904657315311e-06,0.980332055767206,0.378,0.216,0.00345827504616172,"L5","Fezf2"
350 | "Anapc131",3.49312885185784e-06,0.566151704288694,0.436,0.247,0.003562991428895,"L5","Anapc13"
351 | "Sulf2",3.68460915871754e-06,0.8274972940158,0.359,0.195,0.00375830134189189,"L5","Sulf2"
352 | "Tox",2.17930152947759e-05,0.678338214235714,0.365,0.202,0.0222288756006714,"L5","Tox"
353 | "Efr3a1",5.97591545550578e-05,0.680553230970455,0.487,0.339,0.060954337646159,"L5","Efr3a"
354 | "Tmsb10",6.61941667368351e-05,0.885410587943005,0.404,0.266,0.0675180500715718,"L5","Tmsb10"
355 | "Idi11",0.000114066445762561,0.521633027467969,0.301,0.167,0.116347774677813,"L5","Idi1"
356 | "Slc20a1",0.000125825064446289,0.614342391972575,0.571,0.445,0.128341565735214,"L5","Slc20a1"
357 | "Laptm4b",0.000175523696477438,0.563410610885911,0.378,0.231,0.179034170406987,"L5","Laptm4b"
358 | "Arhgap24",0.000189285439397162,0.718105721633704,0.308,0.181,0.193071148185106,"L5","Arhgap24"
359 | "Slc50a1",0.000270235187178041,0.663707875813582,0.353,0.211,0.275639890921602,"L5","Slc50a1"
360 | "Olfm3",0.000347181192399136,0.709102595125416,0.276,0.156,0.354124816247119,"L5","Olfm3"
361 | "Mal2",0.000502614732431163,0.570475303454775,0.526,0.395,0.512667027079787,"L5","Mal2"
362 | "Rit21",0.000645006013593175,0.612617572784265,0.41,0.283,0.657906133865039,"L5","Rit2"
363 | "Gprasp2",0.000681653207866171,0.65715363294497,0.404,0.276,0.695286272023494,"L5","Gprasp2"
364 | "Crhbp",0.000738715868197462,0.528558555166883,0.301,0.181,0.753490185561412,"L5","Crhbp"
365 | "Sgpp2",0.000969523887882986,0.63751746543519,0.244,0.141,0.988914365640645,"L5","Sgpp2"
366 | "Acot13",0.00116913906352585,0.51021454615469,0.436,0.311,1,"L5","Acot13"
367 | "Dnajc15",0.00119486002705249,0.565368628002348,0.551,0.42,1,"L5","Dnajc15"
368 | "Adgra1",0.00124569192967915,0.592656784359516,0.205,0.11,1,"L5","Adgra1"
369 | "Rab3b",0.00221183342026901,0.57936010409987,0.34,0.225,1,"L5","Rab3b"
370 | "Anxa5",0.0026573174079258,0.518306221201035,0.282,0.181,1,"L5","Anxa5"
371 | "Slc25a11",0.00266292891045283,0.598886733354276,0.359,0.247,1,"L5","Slc25a11"
372 | "Amph",0.0042849472289602,0.515273750924067,0.429,0.324,1,"L5","Amph"
373 | "Rab27b",0.00444507696220729,0.575662238664093,0.218,0.13,1,"L5","Rab27b"
374 | "Elavl2",0.00469807903023228,0.540392318558157,0.224,0.136,1,"L5","Elavl2"
375 | "Nr1d1",0.00494925643051289,0.655533203608875,0.16,0.088,1,"L5","Nr1d1"
376 | "Gad1",0.00543169346243443,0.721267485375603,0.423,0.306,1,"L5","Gad1"
377 | "Cd200",0.00588876263514452,0.548156648370005,0.256,0.166,1,"L5","Cd200"
378 | "Twistnb1",0.00592122977380668,0.599716893733918,0.256,0.163,1,"L5","Twistnb"
379 | "Pdgfra",0.00617371448792396,0.881090991840061,0.192,0.114,1,"L5","Pdgfra"
380 | "Fam3c",0.00656137317615804,0.61803666253139,0.301,0.208,1,"L5","Fam3c"
381 | "Plpp4",0.00692290544003753,0.634205777472684,0.224,0.141,1,"L5","Plpp4"
382 | "St6galnac51",0.00696752123081033,0.546678751519693,0.372,0.277,1,"L5","St6galnac5"
383 |
--------------------------------------------------------------------------------
/AnalysisPaper/output/figure2/distance_to_l1_151507_original.csv:
--------------------------------------------------------------------------------
1 | "","group","median","sd"
2 | "1","Layer1",0.197329648331798,0.138248614724038
3 | "2","Layer2",0.240193568861839,0.141861819292885
4 | "3","Layer3",0.338599407477968,0.137529247776075
5 | "4","Layer4",0.440474973248037,0.111503487438145
6 | "5","Layer5",0.517061341457862,0.106592625325505
7 | "6","Layer6",0.60441227477659,0.0948704974081041
8 | "7","WM",0.668523321707473,0.0731724127707
9 |
--------------------------------------------------------------------------------
/AnalysisPaper/output/figure2/distance_to_l1_151507_pseudo.csv:
--------------------------------------------------------------------------------
1 | "","group","median","sd"
2 | "1","Layer1",0.212517556251342,0.15375562145406
3 | "2","Layer2",0.199590703756467,0.137133253784138
4 | "3","Layer3",0.249105617452126,0.143513436977813
5 | "4","Layer4",0.384913825671047,0.129044347097029
6 | "5","Layer5",0.496253533366634,0.117886051216469
7 | "6","Layer6",0.509793886120562,0.122359318351796
8 | "7","WM",0.645103658469303,0.129656513663322
9 |
--------------------------------------------------------------------------------
/AnalysisPaper/output/figure2/distance_to_l1_151508_original.csv:
--------------------------------------------------------------------------------
1 | "","group","median","sd"
2 | "1","Layer1",0.198943870183798,0.140772876132374
3 | "2","Layer2",0.231014458895045,0.136595947249676
4 | "3","Layer3",0.335117027843194,0.138686300620042
5 | "4","Layer4",0.442452890131467,0.113800465674267
6 | "5","Layer5",0.526034673260964,0.113031374110587
7 | "6","Layer6",0.606788732365734,0.0865901558734091
8 | "7","WM",0.679455298601748,0.064470683959494
9 |
--------------------------------------------------------------------------------
/AnalysisPaper/output/figure2/distance_to_l1_151508_pseudo.csv:
--------------------------------------------------------------------------------
1 | "","group","median","sd"
2 | "1","Layer1",0.202865409148947,0.150255053656419
3 | "2","Layer2",0.196402708483338,0.142325436811784
4 | "3","Layer3",0.237407894907841,0.13896717744907
5 | "4","Layer4",0.377195042531555,0.125455029364853
6 | "5","Layer5",0.465464400260658,0.107794015139785
7 | "6","Layer6",0.475671031431022,0.126703329387119
8 | "7","WM",0.643373208698139,0.099459272644238
9 |
--------------------------------------------------------------------------------
/AnalysisPaper/output/figure2/distance_to_l1_151509_original.csv:
--------------------------------------------------------------------------------
1 | "","group","median","sd"
2 | "1","Layer1",0.252530403204514,0.184798896186719
3 | "2","Layer2",0.263730088092511,0.166796003477036
4 | "3","Layer3",0.341144381242619,0.161180367970948
5 | "4","Layer4",0.414824202727001,0.120246299770432
6 | "5","Layer5",0.468893829390011,0.0975912354236254
7 | "6","Layer6",0.527435860991588,0.0773841371352227
8 | "7","WM",0.586847701219648,0.0662481899656655
9 |
--------------------------------------------------------------------------------
/AnalysisPaper/output/figure2/distance_to_l1_151509_pseudo.csv:
--------------------------------------------------------------------------------
1 | "","group","median","sd"
2 | "1","Layer1",0.225655560210892,0.159129720879418
3 | "2","Layer2",0.211424789985437,0.139624630253975
4 | "3","Layer3",0.33716323824874,0.152204558091647
5 | "4","Layer4",0.48293479743954,0.124066049233649
6 | "5","Layer5",0.565867716737722,0.113451241713318
7 | "6","Layer6",0.602508116180567,0.137504702339824
8 | "7","WM",0.750928506255946,0.0847669530980976
9 |
--------------------------------------------------------------------------------
/AnalysisPaper/output/figure2/distance_to_l1_151510_original.csv:
--------------------------------------------------------------------------------
1 | "","group","median","sd"
2 | "1","Layer1",0.2470702882514,0.181520935269487
3 | "2","Layer2",0.262781383790348,0.164536341303683
4 | "3","Layer3",0.340610688561663,0.157089613956383
5 | "4","Layer4",0.406174683937556,0.117651037790995
6 | "5","Layer5",0.452262168904713,0.0993829574730475
7 | "6","Layer6",0.50233497936029,0.0805657395578744
8 | "7","WM",0.556258025801653,0.0753562265453451
9 |
--------------------------------------------------------------------------------
/AnalysisPaper/output/figure2/distance_to_l1_151510_pseudo.csv:
--------------------------------------------------------------------------------
1 | "","group","median","sd"
2 | "1","Layer1",0.222579644799859,0.145835589044463
3 | "2","Layer2",0.207459363595504,0.131429643171032
4 | "3","Layer3",0.306465000916702,0.145129086110078
5 | "4","Layer4",0.451865227685913,0.123848396513803
6 | "5","Layer5",0.516930692864692,0.112067547008295
7 | "6","Layer6",0.539881538336815,0.118542292450424
8 | "7","WM",0.691399433988576,0.11256861171043
9 |
--------------------------------------------------------------------------------
/AnalysisPaper/output/figure2/distance_to_l1_151669_original.csv:
--------------------------------------------------------------------------------
1 | "","group","median","sd"
2 | "1","Layer3",0.30779397572519,0.172537942077569
3 | "2","Layer4",0.385190677341988,0.16749968907067
4 | "3","Layer5",0.451664873509091,0.160890189857129
5 | "4","Layer6",0.508141816371664,0.144347426435665
6 | "5","WM",0.5488848738229,0.122789497936516
7 |
--------------------------------------------------------------------------------
/AnalysisPaper/output/figure2/distance_to_l1_151669_pseudo.csv:
--------------------------------------------------------------------------------
1 | "","group","median","sd"
2 | "1","Layer3",0.245625923808809,0.152339643405181
3 | "2","Layer4",0.282990394396808,0.140249684897574
4 | "3","Layer5",0.384837298148449,0.126807106175433
5 | "4","Layer6",0.441589308665264,0.128721987656123
6 | "5","WM",0.483699066932084,0.128451184379793
7 |
--------------------------------------------------------------------------------
/AnalysisPaper/output/figure2/distance_to_l1_151670_original.csv:
--------------------------------------------------------------------------------
1 | "","group","median","sd"
2 | "1","Layer3",0.322760272745806,0.181965977371495
3 | "2","Layer4",0.388221813038658,0.176040807366736
4 | "3","Layer5",0.444098793582816,0.165404655566769
5 | "4","Layer6",0.512184732436032,0.149717334978403
6 | "5","WM",0.53967518532328,0.126010261367522
7 |
--------------------------------------------------------------------------------
/AnalysisPaper/output/figure2/distance_to_l1_151670_pseudo.csv:
--------------------------------------------------------------------------------
1 | "","group","median","sd"
2 | "1","Layer3",0.238625487749596,0.139363157368343
3 | "2","Layer4",0.268367186389236,0.130141490719731
4 | "3","Layer5",0.379702513117907,0.129420187004209
5 | "4","Layer6",0.456349027301054,0.128506358617817
6 | "5","WM",0.518870373292317,0.130867526662178
7 |
--------------------------------------------------------------------------------
/AnalysisPaper/output/figure2/distance_to_l1_151671_original.csv:
--------------------------------------------------------------------------------
1 | "","group","median","sd"
2 | "1","Layer3",0.276555298295095,0.167438211850936
3 | "2","Layer4",0.33390703086893,0.160356384532328
4 | "3","Layer5",0.389158060584608,0.155820607433449
5 | "4","Layer6",0.484958161328985,0.14571028717906
6 | "5","WM",0.542676479853011,0.11110714837842
7 |
--------------------------------------------------------------------------------
/AnalysisPaper/output/figure2/distance_to_l1_151671_pseudo.csv:
--------------------------------------------------------------------------------
1 | "","group","median","sd"
2 | "1","Layer3",0.227206257962406,0.136836901919176
3 | "2","Layer4",0.276954258650024,0.127134755649102
4 | "3","Layer5",0.351045497768639,0.124872810396624
5 | "4","Layer6",0.410705326063522,0.127413776612128
6 | "5","WM",0.440894459083027,0.151120784456534
7 |
--------------------------------------------------------------------------------
/AnalysisPaper/output/figure2/distance_to_l1_151672_original.csv:
--------------------------------------------------------------------------------
1 | "","group","median","sd"
2 | "1","Layer3",0.253255192641948,0.152837074780972
3 | "2","Layer4",0.330805681821903,0.158162126860343
4 | "3","Layer5",0.386610503751046,0.150023949233117
5 | "4","Layer6",0.497851593912446,0.14214684331381
6 | "5","WM",0.552384182232836,0.108275078234417
7 |
--------------------------------------------------------------------------------
/AnalysisPaper/output/figure2/distance_to_l1_151672_pseudo.csv:
--------------------------------------------------------------------------------
1 | "","group","median","sd"
2 | "1","Layer3",0.191315896370629,0.118493493245797
3 | "2","Layer4",0.232051098863993,0.121775076038264
4 | "3","Layer5",0.30071982703756,0.118377193356874
5 | "4","Layer6",0.385275023816039,0.121931622021851
6 | "5","WM",0.439002679184076,0.148134754736176
7 |
--------------------------------------------------------------------------------
/AnalysisPaper/output/figure2/distance_to_l1_151673_original.csv:
--------------------------------------------------------------------------------
1 | "","group","median","sd"
2 | "1","Layer1",0.154019448357396,0.17864538225862
3 | "2","Layer2",0.475068530427967,0.252204585853915
4 | "3","Layer3",0.424880605251649,0.218897679786899
5 | "4","Layer4",0.40806656671864,0.185124988772152
6 | "5","Layer5",0.421719908227849,0.156051334398587
7 | "6","Layer6",0.493921795961639,0.124685343780026
8 | "7","WM",0.626736688293506,0.111290469220495
9 |
--------------------------------------------------------------------------------
/AnalysisPaper/output/figure2/distance_to_l1_151673_pseudo.csv:
--------------------------------------------------------------------------------
1 | "","group","median","sd"
2 | "1","Layer1",0.208281053268522,0.139732872918143
3 | "2","Layer2",0.351957713674652,0.18622600289134
4 | "3","Layer3",0.363037044631935,0.186154628760291
5 | "4","Layer4",0.355365480062785,0.172475933030016
6 | "5","Layer5",0.384256607145443,0.14975876498441
7 | "6","Layer6",0.44325366585986,0.141320344200917
8 | "7","WM",0.626016853441947,0.118685455958056
9 |
--------------------------------------------------------------------------------
/AnalysisPaper/output/figure2/distance_to_l1_151674_original.csv:
--------------------------------------------------------------------------------
1 | "","group","median","sd"
2 | "1","Layer1",0.182850006551085,0.156905104836389
3 | "2","Layer2",0.414142048912799,0.238987141184158
4 | "3","Layer3",0.404529800380053,0.212066928247357
5 | "4","Layer4",0.433713562003921,0.18155456009671
6 | "5","Layer5",0.422592168346491,0.155551355092788
7 | "6","Layer6",0.481337334019138,0.126933536748408
8 | "7","WM",0.623186508121396,0.11633167382103
9 |
--------------------------------------------------------------------------------
/AnalysisPaper/output/figure2/distance_to_l1_151674_pseudo.csv:
--------------------------------------------------------------------------------
1 | "","group","median","sd"
2 | "1","Layer1",0.19694634368247,0.161164597093986
3 | "2","Layer2",0.410318802748727,0.20864816467765
4 | "3","Layer3",0.375441140498556,0.201693492148243
5 | "4","Layer4",0.385932200675891,0.188369057989506
6 | "5","Layer5",0.366453398842157,0.172921072569737
7 | "6","Layer6",0.388615504088507,0.146628396986829
8 | "7","WM",0.53189854844803,0.106670532953122
9 |
--------------------------------------------------------------------------------
/AnalysisPaper/output/figure2/distance_to_l1_151675_original.csv:
--------------------------------------------------------------------------------
1 | "","group","median","sd"
2 | "1","Layer1",0.185490805260873,0.170945852518
3 | "2","Layer2",0.501822127345392,0.237701798444282
4 | "3","Layer3",0.491261920947984,0.227663887879952
5 | "4","Layer4",0.469046838411899,0.197539680598819
6 | "5","Layer5",0.440762501866766,0.163991782139819
7 | "6","Layer6",0.462455401219036,0.122063406985138
8 | "7","WM",0.563868481550939,0.116735318013122
9 |
--------------------------------------------------------------------------------
/AnalysisPaper/output/figure2/distance_to_l1_151675_pseudo.csv:
--------------------------------------------------------------------------------
1 | "","group","median","sd"
2 | "1","Layer1",0.240255483126917,0.152601697488472
3 | "2","Layer2",0.353867531118287,0.183631984507315
4 | "3","Layer3",0.313657354383713,0.175096703514685
5 | "4","Layer4",0.316142939683562,0.165512787275421
6 | "5","Layer5",0.329445092871112,0.158000302950507
7 | "6","Layer6",0.370241108939219,0.155729000111993
8 | "7","WM",0.561472005763911,0.149685887044217
9 |
--------------------------------------------------------------------------------
/AnalysisPaper/output/figure2/distance_to_l1_151676_original.csv:
--------------------------------------------------------------------------------
1 | "","group","median","sd"
2 | "1","Layer1",0.187514111252809,0.167648365392419
3 | "2","Layer2",0.40666475047655,0.246452953662222
4 | "3","Layer3",0.408384658107067,0.219309420733451
5 | "4","Layer4",0.45675376503599,0.188278691572407
6 | "5","Layer5",0.440555390729101,0.15894958820468
7 | "6","Layer6",0.488706349981301,0.122356649431308
8 | "7","WM",0.631659202672739,0.113713453525755
9 |
--------------------------------------------------------------------------------
/AnalysisPaper/output/figure2/distance_to_l1_151676_pseudo.csv:
--------------------------------------------------------------------------------
1 | "","group","median","sd"
2 | "1","Layer1",0.189178260633007,0.147671923495415
3 | "2","Layer2",0.306682267733961,0.170925778943968
4 | "3","Layer3",0.283823556147635,0.177371625129722
5 | "4","Layer4",0.310880781437735,0.16033475607749
6 | "5","Layer5",0.325589566076085,0.150248652008729
7 | "6","Layer6",0.37731238824046,0.134700679520405
8 | "7","WM",0.552764364605649,0.104304660092355
9 |
--------------------------------------------------------------------------------
/AnalysisPaper/output/figure2/distance_to_l1_starmap_original.csv:
--------------------------------------------------------------------------------
1 | "","group","median","sd"
2 | "1","CC",0.74486579390643,0.0584519542032213
3 | "2","HPC",0.836426778051229,0.0472023701188707
4 | "3","L1",0.134292277045647,0.103583090594067
5 | "4","L2/3",0.215006428252274,0.0919557608314547
6 | "5","L4",0.337776728382412,0.0703287296483846
7 | "6","L5",0.471092163067811,0.0625243511350518
8 | "7","L6",0.614691196110052,0.0620040209675152
9 |
--------------------------------------------------------------------------------
/AnalysisPaper/output/figure2/distance_to_l1_starmap_pseudo.csv:
--------------------------------------------------------------------------------
1 | "","group","median","sd"
2 | "1","CC",0.472490061538829,0.177424199444044
3 | "2","HPC",0.429075637809867,0.198787384844337
4 | "3","L1",0.170162009519315,0.137634938962064
5 | "4","L2/3",0.164081585991465,0.126112726257255
6 | "5","L4",0.191227613302833,0.12540786838298
7 | "6","L5",0.299002535909068,0.161034097302899
8 | "7","L6",0.370036477641814,0.166887067380849
9 |
--------------------------------------------------------------------------------
/AnalysisPaper/output/figure2/pairwise_distance_cor_DLPFC.csv:
--------------------------------------------------------------------------------
1 | "","Slice","Donor","PCC"
2 | "1","151507","Donor 1",0.539
3 | "2","151508","Donor 1",0.547
4 | "3","151509","Donor 1",0.48
5 | "4","151510","Donor 1",0.448
6 | "5","151669","Donor 2",0.567
7 | "6","151670","Donor 2",0.493
8 | "7","151671","Donor 2",0.53
9 | "8","151672","Donor 2",0.527
10 | "9","151673","Donor 3",0.657
11 | "10","151674","Donor 3",0.696
12 | "11","151675","Donor 3",0.623
13 | "12","151676","Donor 3",0.664
14 |
--------------------------------------------------------------------------------
/AnalysisPaper/output/figure2/pairwise_distance_cor_STARmap.csv:
--------------------------------------------------------------------------------
1 | "","Data","PCC"
2 | "1","STARmap",0.53
3 |
--------------------------------------------------------------------------------
/AnalysisPaper/output/figure3/ARI_for_different_cluster_numbers.csv:
--------------------------------------------------------------------------------
1 | "","value","method","index"
2 | "1",0.907676034237221,"scSpace","ARI"
3 | "2",0.158238163332117,"Seurat","ARI"
4 | "3",0.846454495931088,"scSpace","NMI"
5 | "4",0.179361123288796,"Seurat","NMI"
6 |
--------------------------------------------------------------------------------
/AnalysisPaper/output/figure3/Clustering_result_for_cardiomyocytes.csv:
--------------------------------------------------------------------------------
1 | "","value","method","index"
2 | "1",0.907676034237221,"scSpace","ARI"
3 | "2",0.158238163332117,"Seurat","ARI"
4 | "3",0.846454495931088,"scSpace","NMI"
5 | "4",0.179361123288796,"Seurat","NMI"
6 |
--------------------------------------------------------------------------------
/AnalysisPaper/output/figure4/ARI_all.csv:
--------------------------------------------------------------------------------
1 | "","type","scSpace","Seurat"
2 | "1","RORB",0.813,0.681
3 | "2","FEZF2",0.919,0.714
4 | "3","THEMIS",0.414,0.251
5 | "4","L2–L3",0.362,0.175
6 | "5","LAMP5/PAX6",0.895,0.789
7 | "6","VIP",0.759,0.655
8 | "7","SST",0.708,0.614
9 | "8","PVALB",0.551,0.55
10 |
--------------------------------------------------------------------------------
/AnalysisPaper/output/figure5/GSEA_result.csv:
--------------------------------------------------------------------------------
1 | "","pathway","pval","padj","ES","NES","nMoreExtreme","size"
2 | "1","HALLMARK_ADIPOGENESIS",0.000145985401459854,0.000815128790348875,0.473033230532222,1.7877373985269,0,188
3 | "2","HALLMARK_ALLOGRAFT_REJECTION",0.693736229146994,0.941716964694232,-0.230321433775538,-0.929794261472289,2203,184
4 | "3","HALLMARK_ANDROGEN_RESPONSE",0.838983050847458,1,0.240384308234869,0.832740962089934,5345,94
5 | "4","HALLMARK_ANGIOGENESIS",0.921779516010755,1,-0.242659442044373,-0.729923810500451,3770,31
6 | "5","HALLMARK_APICAL_JUNCTION",0.722256664600124,0.941716964694232,-0.230648766038081,-0.920341565910592,2329,167
7 | "6","HALLMARK_APICAL_SURFACE",0.946913580246914,1,-0.230754829346362,-0.705532645269124,3834,33
8 | "7","HALLMARK_APOPTOSIS",0.607763788968825,0.868233984241179,0.255452495633045,0.94298298879326,4054,153
9 | "8","HALLMARK_BILE_ACID_METABOLISM",0.548310704136407,0.820188777359323,0.278428717907793,0.959122346033931,3472,90
10 | "9","HALLMARK_CHOLESTEROL_HOMEOSTASIS",0.101239336874296,0.180784530132671,0.375665377942124,1.24754259758152,628,72
11 | "10","HALLMARK_COAGULATION",0.996125232486051,1,0.194838047983654,0.68480693756566,6426,103
12 | "11","HALLMARK_COMPLEMENT",0.970446232626189,1,0.208541812907261,0.784003177907402,6632,178
13 | "12","HALLMARK_DNA_REPAIR",0.000150875075437538,0.000815128790348875,0.571238664754423,2.09176854379379,0,144
14 | "13","HALLMARK_E2F_TARGETS",0.000145053669857847,0.000815128790348875,0.746754489313043,2.83311950662441,0,196
15 | "14","HALLMARK_EPITHELIAL_MESENCHYMAL_TRANSITION",0.999854545454545,1,0.182551716445376,0.691021205997203,6873,191
16 | "15","HALLMARK_ESTROGEN_RESPONSE_EARLY",0.716127004086765,0.941716964694232,-0.229982003189737,-0.922818536477217,2277,175
17 | "16","HALLMARK_ESTROGEN_RESPONSE_LATE",0.00691583284284873,0.0172895821071218,0.376487107815253,1.40554944849286,46,166
18 | "17","HALLMARK_FATTY_ACID_METABOLISM",0.000151285930408472,0.000815128790348875,0.550061058993861,2.00190689975318,0,136
19 | "18","HALLMARK_G2M_CHECKPOINT",0.000145666423889294,0.000815128790348875,0.685630341592884,2.59661796889665,0,193
20 | "19","HALLMARK_GLYCOLYSIS",0.00102519039250146,0.00341730130833822,0.404125303419109,1.51968744711401,6,179
21 | "20","HALLMARK_HEDGEHOG_SIGNALING",0.734539232461501,0.941716964694232,-0.280876433799936,-0.844881184559624,3004,31
22 | "21","HALLMARK_HEME_METABOLISM",0.856469201296787,1,0.227830996402504,0.852206677128784,5811,170
23 | "22","HALLMARK_HYPOXIA",0.521629302178718,0.819857570034624,-0.243257859386618,-0.976429677295414,1651,178
24 | "23","HALLMARK_IL2_STAT5_SIGNALING",0.954730713245997,1,0.213205460946534,0.806531043399431,6558,189
25 | "24","HALLMARK_IL6_JAK_STAT3_SIGNALING",0.55772836860434,0.820188777359323,-0.266723405557102,-0.954961834561975,2081,77
26 | "25","HALLMARK_INFLAMMATORY_RESPONSE",0.000310945273631841,0.00132992871582083,-0.396120014309669,-1.58495370495422,0,170
27 | "26","HALLMARK_INTERFERON_ALPHA_RESPONSE",0.0162856248042593,0.0354035321831724,0.406635151812164,1.41220514629079,103,96
28 | "27","HALLMARK_INTERFERON_GAMMA_RESPONSE",0.00480699198834669,0.0133527555231852,0.370842058249854,1.40445236107413,32,193
29 | "28","HALLMARK_KRAS_SIGNALING_DN",0.0369136830419095,0.0769035063373115,-0.348237028159594,-1.29460333704202,132,98
30 | "29","HALLMARK_KRAS_SIGNALING_UP",0.0772841051314143,0.143118713206323,-0.29747800429618,-1.19035713453346,246,171
31 | "30","HALLMARK_MITOTIC_SPINDLE",0.00058021467943139,0.00207219528368353,0.401881698958156,1.52470309448172,3,196
32 | "31","HALLMARK_MTORC1_SIGNALING",0.000144885540423066,0.000815128790348875,0.565078439556365,2.14591739905645,0,198
33 | "32","HALLMARK_MYC_TARGETS_V1",0.000145369966564908,0.000815128790348875,0.685685823478655,2.59956355879781,0,195
34 | "33","HALLMARK_MYC_TARGETS_V2",0.000163025758069775,0.000815128790348875,0.608147495501743,1.94663600162175,0,57
35 | "34","HALLMARK_MYOGENESIS",1,1,0.172768849882386,0.64151591566247,6717,160
36 | "35","HALLMARK_NOTCH_SIGNALING",0.356637466307278,0.61489218328841,0.368175611511476,1.05980956474155,2116,32
37 | "36","HALLMARK_OXIDATIVE_PHOSPHORYLATION",0.000144885540423066,0.000815128790348875,0.702532528567875,2.66790709204992,0,198
38 | "37","HALLMARK_P53_PATHWAY",0.524708844822159,0.819857570034624,-0.242205937172768,-0.977771311971033,1666,184
39 | "38","HALLMARK_PANCREAS_BETA_CELLS",0.410980256321441,0.684967093869068,0.408039673535848,1.03134693061056,2372,18
40 | "39","HALLMARK_PEROXISOME",0.00408035153797866,0.0120010339352313,0.442020584609729,1.53125072761329,25,94
41 | "40","HALLMARK_PI3K_AKT_MTOR_SIGNALING",0.0531333020784498,0.1062666041569,0.371710120212382,1.29521461323893,339,98
42 | "41","HALLMARK_PROTEIN_SECRETION",0.0108354271356784,0.0246259707629054,0.419783342356244,1.45546247633106,68,95
43 | "42","HALLMARK_REACTIVE_OXYGEN_SPECIES_PATHWAY",0.00858369098712446,0.0204373594931535,0.512171576348852,1.58614604691741,51,47
44 | "43","HALLMARK_SPERMATOGENESIS",0.00650587115201523,0.0171207135579348,0.444545915447562,1.50887888745246,40,82
45 | "44","HALLMARK_TGF_BETA_SIGNALING",0.968895800933126,1,-0.215820826890473,-0.722223553421729,3737,53
46 | "45","HALLMARK_TNFA_SIGNALING_VIA_NFKB",0.000319182891797,0.00132992871582083,-0.417460696110903,-1.69145406958398,0,190
47 | "46","HALLMARK_UNFOLDED_PROTEIN_RESPONSE",0.000153846153846154,0.000815128790348875,0.530195959960339,1.88468837520034,0,112
48 | "47","HALLMARK_UV_RESPONSE_DN",0.0731707317073171,0.140712945590994,-0.309426481747035,-1.20838117010628,245,139
49 | "48","HALLMARK_UV_RESPONSE_UP",0.000451807228915663,0.00173772011121409,0.434129173724031,1.58427783380834,2,139
50 | "49","HALLMARK_WNT_BETA_CATENIN_SIGNALING",0.853097345132743,1,-0.252073945252107,-0.795016771738154,3373,39
51 | "50","HALLMARK_XENOBIOTIC_METABOLISM",0.00282780175621372,0.00883688048816788,0.392116960983058,1.45427652382292,18,158
52 |
--------------------------------------------------------------------------------
/AnalysisPaper/output/figure6/Dist_change_ratio.csv:
--------------------------------------------------------------------------------
1 | "","celltype","control_median","covid19_median","ratio"
2 | "1","AM",0.120679693639927,0.103153042608924,-0.145232810113827
3 | "2","MDM",0.181064172561014,0.134254102366538,-0.258527512828095
4 | "3","Mon",0.24632290261257,0.214764795923339,-0.128116818836238
5 | "4","TMDM",0.263944593316936,0.147072092370401,-0.44279179761867
6 |
--------------------------------------------------------------------------------
/AnalysisPaper/output/figure6/MT_gene_average_expression.csv:
--------------------------------------------------------------------------------
1 | "","C_1","C_2","C_3","C_4","C_5","C_6"
2 | "MT-ND1",0.231297049586777,0.300897144329897,0.205432766497462,1.83146648924731,0.569228556962025,1.40658024242424
3 | "MT-ND4",0.329016198347107,0.660310189690722,0.406537649746193,2.6639996827957,0.777941708860759,1.46578881818182
4 | "MT-CYB",0.238227961432507,0.299283560137457,0.134386416243655,1.75342487634409,0.542693139240506,1.34050221212121
5 | "MT-ATP8",0.192374652892562,0.241697766323024,0.100858629441624,1.23616382795699,0.221698329113924,0.433765848484849
6 | "MT-ND3",0.586918834710744,0.616542810996564,0.525844345177665,2.9028886344086,0.779377848101266,1.96618639393939
7 | "MT-ND5",0.228334804407714,0.402755467353952,0.125502664974619,1.63429724731183,0.344462506329114,1.11634378787879
8 | "MT-ND2",0.319205289256198,0.527606914089347,0.339657010152284,1.96967562365591,0.465962544303798,1.57816006060606
9 | "MT-ATP6",0.496659537190083,0.748539594501718,0.443872756345178,2.76538243548387,1.00185181012658,1.49559603030303
10 | "MT-CO3",0.582996834710744,0.773146054982818,0.342607045685279,2.7347715,0.847773329113924,1.95953409090909
11 | "MT-ND6",0.21430179338843,0.330781594501718,0.223954411167513,1.34334100537634,0.60892382278481,0.722972272727273
12 | "MT-ND4L",0.17562176584022,0.266134797938144,0.156623294416244,0.954142010752688,0.328275772151899,0.626834060606061
13 | "MT-CO2",0.680547041322314,1.3395879862543,0.755080604060914,3.23587821505376,1.51485532911392,2.43138703030303
14 | "MT-CO1",0.728609961432507,1.52699816151203,0.694794659898477,3.00887181182796,1.66646802531646,2.31428633333333
15 |
--------------------------------------------------------------------------------
/AnalysisPaper/output/figure6/non_MT_gene_average_expression.csv:
--------------------------------------------------------------------------------
1 | "","C_1","C_2","C_3","C_4","C_5","C_6"
2 | "B2M",0.20569564738292,0.404019859793814,0.494277878172589,0.824000564516129,0.542335012658228,0.187391818181818
3 | "APOE",0.168406462809917,0.580906350515464,0.523299964467005,0.891078338709678,0.346512835443038,0.0575426363636364
4 | "LNCAROD",0.434527327823692,0.384753319587629,0.152099426395939,0.833247704301075,0.239524,0.0688387272727273
5 | "C1QA",0.224390812208599,0.0997298176841053,0.211197040837158,0.566447863455948,0.0179016672334687,0.309833563254096
6 | "TMSB4X",0.0746418925619835,0.153975048109966,0.0747703807106599,0.347380005376344,0.0974386582278481,0.192052212121212
7 | "NUPR1",0.0598423195592287,0.0760115195876289,0.0599113654822335,0.311116129032258,0,0.165610757575758
8 | "TMEM51",0.356061094549742,0.344315162180966,0.319403707141553,0.737180528969658,0.325279006521117,0.285374091021088
9 | "KCTD12",0.136673619834711,0.0863965223367697,0.0978311269035533,0.384580865591398,0.182562227848101,0
10 | "RNASE1",0.0577471101928375,0.037775852233677,0.0254212994923858,0.229082532258065,0.0276699620253165,0
11 | "GRN",0.223368694214876,0.363502350515464,0.284514045685279,0.685795559139785,0.246496772151899,0.510545606060606
12 | "ZBTB1",0.262206438016529,0.192283454295533,0.30706321319797,0.633786526881721,0.196939189873418,0.337721848484848
13 | "SSBP3",0.127525822262054,0.175690991592525,0.0891139607982365,0.400137798461434,0.349862630838014,0.142280301563719
14 | "HLA-DRA",0.322114308539945,0.259609388316151,0.502133482233502,0.743136532258065,0.278202202531646,0.341613909090909
15 | "CD74",0.731048922865014,0.432302195876289,0.698672228426396,1.05026136021505,0.334772759493671,0.571854939393939
16 | "FTL",0.286124027548209,1.20050494158076,0.409344649746193,1.15431317204301,0.999123443037975,0.709243212121212
17 | "CEBPD",0.159908013774105,0.122629312714777,0.133116888324873,0.389841258064516,0.0965949873417722,0
18 | "EPSTI1",0.808204157024794,0.346208316838488,0.587017563451777,1.01788706989247,0.343794088607595,0.585042454545455
19 | "NLRC5",0.230640603305785,0.161142890034364,0.25049938071066,0.531693553763441,0.148480050632911,0.130398606060606
20 | "ORMDL1",0.252074280991736,0.106465107216495,0.140014319796954,0.419950392473118,0.116680240506329,0.124259454545455
21 | "SBNO2",0.121758013774105,0.120490079037801,0.12379585786802,0.344850204301075,0.211652746835443,0.302899121212121
22 | "NUDCD3",0.140784829201102,0.263814907216495,0.100575406091371,0.434911801075269,0.21045953164557,0.196487696969697
23 | "CORO2A",0.0464734573002755,0.089172618556701,0.0443793045685279,0.236807876344086,0.0511561518987342,0.214941939393939
24 | "QSOX1",0.0512611955922865,0.0815533848797251,0.100905284263959,0.237090080645161,0.0682135949367089,0
25 | "ST8SIA4",0.714221016528926,0.327679494845361,0.518003736040609,0.931495258064516,0.198146772151899,0.0601942121212121
26 | "MAFB",0.443195184573003,0.25336335395189,0.231706659898477,0.661798661290322,0.15651046835443,0
27 | "CTSS",0.630552463804256,0.643241499986499,0.657019272932963,1.1031355205923,0.456569204564005,0.384596233424328
28 | "BTG1",0.109431674931129,0.137119402061856,0.310012888324873,0.405936543010753,0.173253075949367,0.0601942121212121
29 | "CLIC4",0.24038246230117,0.287467930917675,0.100562321169233,0.514238484153576,0.228908002274329,0.361177083184399
30 | "CD14",0.150442917355372,0.0681905120274914,0.0577950710659898,0.270045870967742,0,0.0820338484848485
31 | "CARD8",0.437407666666666,0.282765055670103,0.322919091370558,0.674616935483871,0.266315075949367,0.116622333333333
32 | "NFATC3",0.211996033057851,0.150225890034364,0.17802276142132,0.444490478494624,0.0784791392405063,0.470149272727273
33 | "RAPGEF6",0.281813247933884,0.340403811683849,0.320305781725888,0.623271672043011,0.285229088607595,0.561532424242424
34 | "INO80D",0.0904273581267218,0.188884931271478,0.0689242436548223,0.317627005376344,0.0604965316455696,0.223075333333333
35 | "ZNF292",0.482683556473829,0.528319398625429,0.52599945177665,0.891786827956989,0.464949113924051,0.405262272727273
36 | "PIK3AP1",0.431094517906336,0.369089326460481,0.333376228426396,0.744498849462366,0.15869746835443,0.217925121212121
37 |
--------------------------------------------------------------------------------
/AnalysisPaper/output/figure6/ssGSEA_result.csv:
--------------------------------------------------------------------------------
1 | "","disease","variable","value"
2 | "977","COVID-19","Myeloid",0.250216330522536
3 | "978","COVID-19","Myeloid",0.257042670080023
4 | "979","COVID-19","Myeloid",0.289877759408376
5 | "980","COVID-19","Myeloid",0.268328541506847
6 | "981","COVID-19","Myeloid",0.111003251728532
7 | "982","COVID-19","Myeloid",0.267138715197911
8 | "983","COVID-19","Myeloid",0.228118707508618
9 | "984","COVID-19","Myeloid",0.324611135278463
10 | "985","COVID-19","Myeloid",0.427299959002135
11 | "986","COVID-19","Myeloid",0.518426748201658
12 | "987","COVID-19","Myeloid",0.480363677375948
13 | "988","COVID-19","Myeloid",0.535119501410866
14 | "989","COVID-19","Myeloid",0.484038462224725
15 | "990","COVID-19","Myeloid",0.439226102753258
16 | "991","COVID-19","Myeloid",0.424029452116435
17 | "992","COVID-19","Myeloid",0.490584508473879
18 | "993","COVID-19","Myeloid",0.472840616793531
19 | "994","COVID-19","Myeloid",0.524088530108296
20 | "995","COVID-19","Myeloid",0.448073197984175
21 | "996","COVID-19","Myeloid",0.522415289098544
22 | "997","COVID-19","Myeloid",0.530102043416498
23 | "998","COVID-19","Myeloid",0.356594259033859
24 | "999","COVID-19","Myeloid",0.346930998997875
25 | "1000","Control","Myeloid",0.168869046379169
26 | "1001","Control","Myeloid",0.245231258396033
27 | "1002","Control","Myeloid",0.122239114804703
28 | "1003","Control","Myeloid",0.169053706320242
29 | "1004","Control","Myeloid",0.150840724629503
30 | "1005","Control","Myeloid",0.234373686768022
31 | "1006","Control","Myeloid",0.273242381218786
32 | "1007","Control","Myeloid",0.482515855658245
33 | "1008","Control","Myeloid",0.289627484488308
34 | "1009","Control","Myeloid",0.575287916540144
35 | "1010","Control","Myeloid",0.380250909947243
36 | "1011","Control","Myeloid",0.583735717250285
37 | "1012","Control","Myeloid",0.232988094882467
38 | "1013","Control","Myeloid",0.416593397636617
39 | "1014","Control","Myeloid",0.384827117077745
40 | "1015","Control","Myeloid",0.413502263569643
41 | "1016","Control","Myeloid",0.378917415358689
42 | "1017","Control","Myeloid",0.316027470767798
43 | "1018","Control","Myeloid",0.433736675807924
44 | "1019","Control","Myeloid",0.389311387490264
45 | "1020","Control","Myeloid",0.360968004220946
46 | "1021","Control","Myeloid",0.483531867821283
47 | "1022","COVID-19","Myeloid",0.132041418281901
48 | "1023","COVID-19","Myeloid",0.124312449514217
49 | "1024","COVID-19","Myeloid",0.0352520268314382
50 | "1025","COVID-19","Myeloid",0.129323638263956
51 | "1026","COVID-19","Myeloid",0.103168123312864
52 | "1027","COVID-19","Myeloid",0.070037622502905
53 | "1028","COVID-19","Myeloid",0.0651099221550926
54 | "1029","COVID-19","Myeloid",0.0901340629002115
55 | "1030","COVID-19","Myeloid",0.154368901200124
56 | "1031","COVID-19","Myeloid",0.0718807798869372
57 | "1032","COVID-19","Myeloid",0.0796683387190691
58 | "1033","COVID-19","Myeloid",0.0761774376456127
59 | "1034","COVID-19","Myeloid",0.113791091418718
60 | "1035","COVID-19","Myeloid",0.0766786429578902
61 | "1036","COVID-19","Myeloid",0.0630770918470935
62 | "1037","COVID-19","Myeloid",0.0937435285450163
63 | "1038","COVID-19","Myeloid",0.125570831682835
64 | "1039","COVID-19","Myeloid",0.0675352828007507
65 | "1040","COVID-19","Myeloid",0.113808896909273
66 | "1041","COVID-19","Myeloid",0.162003520854102
67 | "1042","COVID-19","Myeloid",0.0417663254765865
68 | "1043","COVID-19","Myeloid",0.0840876744815573
69 | "1044","COVID-19","Myeloid",0.08614513508155
70 | "1045","Control","Myeloid",0.124703237018605
71 | "1046","Control","Myeloid",0.103897824943501
72 | "1047","Control","Myeloid",0.253801606916278
73 | "1048","Control","Myeloid",0.0283000475640489
74 | "1049","Control","Myeloid",0.183491322546951
75 | "1050","Control","Myeloid",0.106036420219941
76 | "1051","Control","Myeloid",0.255134889784557
77 | "1052","Control","Myeloid",0.338627111657275
78 | "1053","Control","Myeloid",0.323499016345883
79 | "1054","Control","Myeloid",0.220200161460239
80 | "1055","Control","Myeloid",0.277929531634428
81 | "1056","Control","Myeloid",0.101284030410977
82 | "1057","Control","Myeloid",0.117984492788774
83 | "1058","Control","Myeloid",0.195380730903008
84 | "1059","Control","Myeloid",0.197285424541955
85 | "1060","Control","Myeloid",0.196936698646052
86 | "1061","Control","Myeloid",0.28077289086498
87 | "1062","Control","Myeloid",0.284140944300338
88 | "1063","Control","Myeloid",0.246389873100444
89 | "1064","Control","Myeloid",0.190000117825656
90 | "1065","Control","Myeloid",0.269913468744485
91 | "1066","Control","Myeloid",0.176122420058492
92 | "1067","Control","Myeloid",0.114078758876183
93 | "1068","COVID-19","Myeloid",0.352903451619908
94 | "1069","COVID-19","Myeloid",0.396026379179117
95 | "1070","COVID-19","Myeloid",0.479416105354856
96 | "1071","COVID-19","Myeloid",0.511804938597068
97 | "1072","COVID-19","Myeloid",0.391958385871834
98 | "1073","COVID-19","Myeloid",0.706366859783305
99 | "1074","COVID-19","Myeloid",0.760582338775417
100 | "1075","COVID-19","Myeloid",0.717121953461032
101 | "1076","COVID-19","Myeloid",0.674461062654381
102 | "1077","COVID-19","Myeloid",0.683925967550615
103 | "1078","COVID-19","Myeloid",0.659674528423622
104 | "1079","COVID-19","Myeloid",0.677603004153992
105 | "1080","COVID-19","Myeloid",0.65808146520862
106 | "1081","COVID-19","Myeloid",0.691979184396187
107 | "1082","COVID-19","Myeloid",0.6657007089639
108 | "1083","COVID-19","Myeloid",0.676918581636171
109 | "1084","COVID-19","Myeloid",0.70804725051815
110 | "1085","COVID-19","Myeloid",0.696858991737869
111 | "1086","COVID-19","Myeloid",0.678977311083836
112 | "1087","COVID-19","Myeloid",0.643803365954467
113 | "1088","COVID-19","Myeloid",0.635153265451139
114 | "1089","COVID-19","Myeloid",0.683930129529293
115 | "1090","COVID-19","Myeloid",0.648608973017835
116 | "1091","COVID-19","Myeloid",0.322311433439173
117 | "1092","COVID-19","Myeloid",0.240134801469837
118 | "1093","COVID-19","Myeloid",0.224110704652504
119 | "1094","COVID-19","Myeloid",0.324638839095094
120 | "1095","COVID-19","Myeloid",0.297156675017905
121 | "1096","COVID-19","Myeloid",0.401810298133974
122 | "1097","COVID-19","Myeloid",0.484282306394555
123 | "1098","COVID-19","Myeloid",0.279895270016135
124 | "1099","COVID-19","Myeloid",0.438087309857773
125 | "1100","COVID-19","Myeloid",0.448344259405202
126 | "1101","COVID-19","Myeloid",0.278110364099112
127 | "1102","COVID-19","Myeloid",0.452085684766527
128 | "1103","COVID-19","Myeloid",0.39278854677679
129 | "1104","COVID-19","Myeloid",0.503080694054639
130 | "1105","COVID-19","Myeloid",0.454262860267709
131 | "1106","COVID-19","Myeloid",0.507896433774613
132 | "1107","COVID-19","Myeloid",0.484190103850124
133 | "1108","COVID-19","Myeloid",0.419607011297767
134 | "1109","COVID-19","Myeloid",0.530664651688186
135 | "1110","COVID-19","Myeloid",0.375787300436132
136 | "1111","COVID-19","Myeloid",0.499902749912325
137 | "1112","COVID-19","Myeloid",0.427780655015945
138 | "1113","COVID-19","Myeloid",0.551283994038418
139 | "1114","COVID-19","Myeloid",0.3984555299099
140 | "1115","Control","Myeloid",0.190808567482629
141 | "1116","Control","Myeloid",0.165657072499745
142 | "1117","Control","Myeloid",0.114751047500808
143 | "1118","Control","Myeloid",0.0783549809056183
144 | "1119","Control","Myeloid",0.0951337847094103
145 | "1120","Control","Myeloid",0.116676605301746
146 | "1121","Control","Myeloid",0.329515436482466
147 | "1122","Control","Myeloid",0.229738102680809
148 | "1123","Control","Myeloid",0.161208479066802
149 | "1124","Control","Myeloid",0.128943791897934
150 | "1125","Control","Myeloid",0.148445712629508
151 | "1126","Control","Myeloid",0.187928185136822
152 | "1127","Control","Myeloid",0.212418972480923
153 | "1128","Control","Myeloid",0.205373719409626
154 | "1129","Control","Myeloid",0.176217741817391
155 | "1130","Control","Myeloid",0.145189331493049
156 | "1131","Control","Myeloid",0.253654750234779
157 | "1132","Control","Myeloid",0.172609335595715
158 | "1133","Control","Myeloid",0.220393576321199
159 | "1134","COVID-19","Myeloid",0.122734874366942
160 | "1135","COVID-19","Myeloid",0.162379679211496
161 | "1136","COVID-19","Myeloid",0.267936716799857
162 | "1137","COVID-19","Myeloid",0.330161096861377
163 | "1138","COVID-19","Myeloid",0.279987872876541
164 | "1139","COVID-19","Myeloid",0.288694592938034
165 | "1140","COVID-19","Myeloid",0.322998817331481
166 | "1141","COVID-19","Myeloid",0.354699236875367
167 | "1142","COVID-19","Myeloid",0.386074833143607
168 | "1143","COVID-19","Myeloid",0.316032944576154
169 | "1144","COVID-19","Myeloid",0.234522593289191
170 | "1145","COVID-19","Myeloid",0.308164813825833
171 | "1146","COVID-19","Myeloid",0.374465705690953
172 | "1147","COVID-19","Myeloid",0.388649534830557
173 | "1148","COVID-19","Myeloid",0.360904391419023
174 | "1149","COVID-19","Myeloid",0.43646601194628
175 | "1150","COVID-19","Myeloid",0.203511623947772
176 | "1151","COVID-19","Myeloid",0.28413996315672
177 | "1152","COVID-19","Myeloid",0.306348886656628
178 | "1153","COVID-19","Myeloid",0.264310390461167
179 | "1154","COVID-19","Myeloid",0.268629419672569
180 | "1155","COVID-19","Myeloid",0.318361003330723
181 | "1156","COVID-19","Myeloid",0.241281398125304
182 | "1157","COVID-19","Myeloid",0.190786891517348
183 | "1158","COVID-19","Myeloid",0.173572259878705
184 | "1159","COVID-19","Myeloid",0.16619620085323
185 | "1160","COVID-19","Myeloid",0.364068704499595
186 | "1161","COVID-19","Myeloid",0.420142244330761
187 | "1162","COVID-19","Myeloid",0.374681518804777
188 | "1163","COVID-19","Myeloid",0.387743691022963
189 | "1164","COVID-19","Myeloid",0.359830214635198
190 | "1165","COVID-19","Myeloid",0.397283781248179
191 | "1166","COVID-19","Myeloid",0.392123893264993
192 | "1167","COVID-19","Myeloid",0.39894671954036
193 | "1168","COVID-19","Myeloid",0.383558137985802
194 | "1169","COVID-19","Myeloid",0.355434364887422
195 | "1170","COVID-19","Myeloid",0.390890635146925
196 | "1171","COVID-19","Myeloid",0.333136742229492
197 | "1172","COVID-19","Myeloid",0.298683361347644
198 | "1173","COVID-19","Myeloid",0.335924869333058
199 | "1174","COVID-19","Myeloid",0.232075954406728
200 | "1175","COVID-19","Myeloid",0.288142521838553
201 | "1176","COVID-19","Myeloid",0.249506103063558
202 | "1177","COVID-19","Myeloid",0.243095654489006
203 | "1178","COVID-19","Myeloid",0.383920561216771
204 | "1179","COVID-19","Myeloid",0.367180949964583
205 | "1180","COVID-19","Myeloid",0.402326310126341
206 | "1181","COVID-19","Myeloid",0.418445969482157
207 | "1182","COVID-19","Myeloid",0.414221621546764
208 | "1183","COVID-19","Myeloid",0.358410423919427
209 | "1184","COVID-19","Myeloid",0.37318772192127
210 | "1185","COVID-19","Myeloid",0.397001262692416
211 | "1186","COVID-19","Myeloid",0.37802841563471
212 | "1187","COVID-19","Myeloid",0.381165986855117
213 | "1188","COVID-19","Myeloid",0.408798298383484
214 | "1189","COVID-19","Myeloid",0.389822405278572
215 | "1190","COVID-19","Myeloid",0.43578554088242
216 | "1191","COVID-19","Myeloid",0.416065415028555
217 | "1192","COVID-19","Myeloid",0.405674286198038
218 | "1193","COVID-19","Myeloid",0.394415327254388
219 | "1194","COVID-19","Myeloid",0.42402382902631
220 | "1195","COVID-19","Myeloid",0.378738820098843
221 | "1196","COVID-19","Myeloid",0.396622251712177
222 | "1197","COVID-19","Myeloid",0.383483240196884
223 | "1198","COVID-19","Myeloid",0.520028078763323
224 | "1199","COVID-19","Myeloid",0.521927331095218
225 | "1200","COVID-19","Myeloid",0.477922637522214
226 | "1201","COVID-19","Myeloid",0.506603776779542
227 | "1202","COVID-19","Myeloid",0.492876607430701
228 | "1203","COVID-19","Myeloid",0.574317130843211
229 | "1204","COVID-19","Myeloid",0.479750868996619
230 | "1205","COVID-19","Myeloid",0.528335689376677
231 | "1206","COVID-19","Myeloid",0.468555056002118
232 | "1207","COVID-19","Myeloid",0.525154153978563
233 | "1208","COVID-19","Myeloid",0.490596261899952
234 | "1209","COVID-19","Myeloid",0.503006631235982
235 | "1210","COVID-19","Myeloid",0.546966502093643
236 | "1211","COVID-19","Myeloid",0.471985707962497
237 | "1212","COVID-19","Myeloid",0.496829723343684
238 | "1213","COVID-19","Myeloid",0.465130568476482
239 | "1214","COVID-19","Myeloid",0.489212794371814
240 | "1215","COVID-19","Myeloid",0.483034091131162
241 | "1216","COVID-19","Myeloid",0.496234665050535
242 | "1217","COVID-19","Myeloid",0.534900407792933
243 | "1218","COVID-19","Myeloid",0.470689461981916
244 | "1219","COVID-19","Myeloid",0.432453262991519
245 | "1220","COVID-19","Myeloid",0.48796714848279
246 |
--------------------------------------------------------------------------------
/AnalysisPaper/scripts/constructSimulations.R:
--------------------------------------------------------------------------------
1 | # simulating paired scRNA-seq and ST data using splatter.
2 | library(splatter)
3 |
4 | # generate gene expression data and spatial coordinates
5 | sim_data_construct <- function(gene_num = 5000,
6 | batch_cell_num_1 = 1000,
7 | batch_cell_num_2 = 1000,
8 | group_prob,
9 | de_prob,
10 | max_range = 20,
11 | seed = 123
12 | ){
13 |
14 | params <- newSplatParams(seed = seed)
15 | params <- setParams(
16 | params,
17 | update = list(nGenes = gene_num,
18 | batchCells = c(batch_cell_num_1, batch_cell_num_2),
19 | group.prob = group_prob,
20 | de.prob = de_prob)
21 | )
22 |
23 | message('Simulating data...')
24 | sim <- splatSimulate(params, method = "group", verbose = FALSE)
25 | counts <- data.frame(sim@assays@data@listData[["counts"]])
26 | meta <- data.frame(sim@colData)
27 | meta$Group <- as.character(meta$Group)
28 |
29 | sc_meta <- meta[meta$Batch == 'Batch1', ]
30 | sc_data <- counts[, rownames(sc_meta)]
31 | message('ScRNA-seq data simulation done...')
32 |
33 | st_meta <- meta[meta$Batch == 'Batch2', ]
34 | st_data <- counts[, rownames(st_meta)]
35 | st_meta$pseudo_x <- 0
36 | st_meta$pseudo_y <- 0
37 |
38 | cell_type_num <- length(group_prob)
39 | cell_type_name <- names(table(st_meta$Group))
40 | cell_num_per_ct <- as.vector(table(st_meta$Group))
41 |
42 | x_center <- sample(-max_range:max_range, cell_type_num)
43 | y_center <- sample(-max_range:max_range, cell_type_num)
44 |
45 | for (i in 1:cell_type_num) {
46 | st_meta[st_meta$Group == cell_type_name[i],]$pseudo_x <- rnorm(cell_num_per_ct[i], x_center[i])
47 | st_meta[st_meta$Group == cell_type_name[i],]$pseudo_y <- rnorm(cell_num_per_ct[i], y_center[i])
48 | }
49 |
50 | message('SrT data simulation done...')
51 | message('Simulating done.')
52 |
53 | return(list(sc_data = sc_data,
54 | sc_meta = sc_meta,
55 | st_data = st_data,
56 | st_meta = st_meta))
57 | }
58 |
59 | # generate proportion of each celltype randomly
60 | generate_ct_prob <- function(ct_num,
61 | seed = 123){
62 | set.seed(seed)
63 | ct_prob <- runif(ct_num, min = 0, max = 1)
64 | ct_prob <- ct_prob / sum(ct_prob)
65 | return(ct_prob)
66 | }
67 |
68 | # generate group differential expression of each celltype randomly, 0.2 for main celltypes and 0.01 for spatial-subtypes
69 | generate_de_prob <- function(ct_num,
70 | sub_ct_num){
71 | de_prob <- c(rep(0.2, (ct_num - sub_ct_num)), rep(0.01, sub_ct_num))
72 | return(de_prob)
73 | }
--------------------------------------------------------------------------------
/AnalysisPaper/scripts/figure1/BayesSpace_DRSC_simulation.R:
--------------------------------------------------------------------------------
1 | source('../scripts/utils.R')
2 |
3 |
4 | ################## DR.SC ##################
5 | sim_id <- paste0('sim', 1:140)
6 | time_df <- data.frame(matrix(ncol = 1, nrow = 140))
7 | rownames(time_df) <- sim_id; colnames(time_df) <- 'run_time'
8 | res_list <- list()
9 | for (i in 1:length(sim_id)) {
10 | if(i <= 50){
11 | data <- read.csv(paste0('~/workspace/scSpace/data/[0]simulated_data/original_data/', sim_id[i], '_sc_data.csv'), row.names = 1)
12 | meta <- read.csv(paste0('~/workspace/scSpace/data/[0]simulated_data/original_data/', sim_id[i], '_sc_meta.csv'), row.names = 1)
13 | pseudo_space <- read.csv(paste0('~/workspace/scSpace/data/[0]simulated_data/pseudo_space/pseudo_coords_', sim_id[i], '.csv'), row.names = 1)
14 | } else if(i > 50){
15 | data <- read.csv(paste0('~/workspace/scSpace/data/add_subcluster/original_data/', sim_id[i], '_sc_data.csv'), row.names = 1)
16 | meta <- read.csv(paste0('~/workspace/scSpace/data/add_subcluster/original_data/', sim_id[i], '_sc_meta.csv'), row.names = 1)
17 | pseudo_space <- read.csv(paste0('~/workspace/scSpace/data/add_subcluster/result/', sim_id[i], '_pseudo_space.csv'), row.names = 1)
18 | }
19 |
20 | meta$row <- pseudo_space[, 1]
21 | meta$col <- pseudo_space[, 2]
22 |
23 | ct_num <- length(unique(meta$Group))
24 | start_time <- Sys.time()
25 | res <- run_DRSC(data = data, meta = meta, cluster_num = ct_num)
26 | end_time <- Sys.time()
27 | time_df$run_time[i] <- as.numeric(difftime(end_time, start_time, units = 'secs'))
28 | res_list[[sim_id[i]]] <- res
29 | }
30 |
31 | save(res_list, file = '~/workspace/scSpace/data/bayesspace/drsc_sim140.Rdata')
32 | write.csv(time_df, file = '~/workspace/scSpace/data/bayesspace/drsc_sim140_runtime.csv')
33 |
34 |
35 | ################## BayesSpace ##################
36 | sim_id <- paste0('sim', 1:140)
37 | time_df <- data.frame(matrix(ncol = 1, nrow = 140))
38 | rownames(time_df) <- sim_id; colnames(time_df) <- 'run_time'
39 | res_list <- list()
40 | for (i in 1:length(sim_id)) {
41 | if(i <= 50){
42 | data <- read.csv(paste0('~/workspace/scSpace/data/[0]simulated_data/original_data/', sim_id[i], '_sc_data.csv'), row.names = 1)
43 | meta <- read.csv(paste0('~/workspace/scSpace/data/[0]simulated_data/original_data/', sim_id[i], '_sc_meta.csv'), row.names = 1)
44 | pseudo_space <- read.csv(paste0('~/workspace/scSpace/data/[0]simulated_data/pseudo_space/pseudo_coords_', sim_id[i], '.csv'), row.names = 1)
45 | } else if(i > 50){
46 | data <- read.csv(paste0('~/workspace/scSpace/data/add_subcluster/original_data/', sim_id[i], '_sc_data.csv'), row.names = 1)
47 | meta <- read.csv(paste0('~/workspace/scSpace/data/add_subcluster/original_data/', sim_id[i], '_sc_meta.csv'), row.names = 1)
48 | pseudo_space <- read.csv(paste0('~/workspace/scSpace/data/add_subcluster/result/', sim_id[i], '_pseudo_space.csv'), row.names = 1)
49 | }
50 |
51 | meta$row <- pseudo_space[, 1]
52 | meta$col <- pseudo_space[, 2]
53 |
54 | ct_num <- length(unique(meta$Group))
55 | start_time <- Sys.time()
56 | res <- run_BayesSpace(data = data, meta = meta, cluster_num = ct_num)
57 | end_time <- Sys.time()
58 | time_df$run_time[i] <- as.numeric(difftime(end_time, start_time, units = 'secs'))
59 | res_list[[sim_id[i]]] <- res
60 | }
61 |
62 | save(res_list, file = '~/workspace/scSpace/data/bayesspace/bayesspace_sim140.Rdata')
63 | write.csv(time_df, file = '~/workspace/scSpace/data/bayesspace/bayesspace_sim140_runtime.csv')
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/AnalysisPaper/scripts/figure2/DLPFC_aggregate.R:
--------------------------------------------------------------------------------
1 | slice_id <- c(151507, 151508, 151509, 151510, 151669, 151670, 151671, 151672, 151673, 151674, 151675, 151676)
2 | data_list <- list(
3 | test_slice = slice_id,
4 | train_slice = list(c(151508, 151509, 151510), c(151507, 151509, 151510), c(151507, 151508, 151510), c(151507, 151508, 151509),
5 | c(151670, 151671, 151672), c(151669, 151671, 151672), c(151669, 151670, 151672), c(151669, 151670, 151671),
6 | c(151674, 151675, 151676), c(151673, 151675, 151676), c(151673, 151674, 151676), c(151673, 151674, 151675)))
7 |
8 |
9 | # pseudo space aggregate
10 | for (i in 1:length(slice_id)) {
11 | test_slice <- data_list$test_slice[i]
12 | original_coord <- read.csv(paste0('~/workspace/scSpace/data/DLPFC_new/data/', test_slice, '_meta.csv'), row.names = 1)
13 |
14 | train_list_tmp <- data_list$train_slice[[i]]
15 |
16 | p1 <- read.csv(paste0('~/workspace/scSpace/data/DLPFC_new/result/',
17 | test_slice, '_pseudo_space(trained_on_', train_list_tmp[1], ').csv'), row.names = 1)
18 | p2 <- read.csv(paste0('~/workspace/scSpace/data/DLPFC_new/result/',
19 | test_slice, '_pseudo_space(trained_on_', train_list_tmp[2], ').csv'), row.names = 1)
20 | p3 <- read.csv(paste0('~/workspace/scSpace/data/DLPFC_new/result/',
21 | test_slice, '_pseudo_space(trained_on_', train_list_tmp[3], ').csv'), row.names = 1)
22 |
23 | p_new <- (p1 + p2 + p3) / 3
24 |
25 | original_coord$pseudo_space1 <- p_new$X0
26 | original_coord$pseudo_space2 <- p_new$X1
27 |
28 | write.csv(original_coord, file = paste0('~/workspace/scSpace/data/DLPFC_new/result/', test_slice, '_pseudo_space_aggregate.csv'))
29 |
30 | }
--------------------------------------------------------------------------------
/AnalysisPaper/scripts/figure3/human_heart.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 1,
6 | "metadata": {},
7 | "outputs": [],
8 | "source": [
9 | "import numpy as np\n",
10 | "import scipy.io\n",
11 | "import scipy.linalg\n",
12 | "import sklearn.metrics\n",
13 | "from sklearn.neighbors import KNeighborsClassifier\n",
14 | "from sklearn.model_selection import train_test_split\n",
15 | "import pandas as pd\n",
16 | "\n",
17 | "import anndata as ad\n",
18 | "import scanpy as sc\n",
19 | "from sklearn.neighbors import KDTree\n",
20 | "import igraph as ig\n",
21 | "from scipy import sparse\n",
22 | "from sklearn.neighbors import KDTree\n",
23 | "from itertools import chain\n",
24 | "\n",
25 | "import numpy as np\n",
26 | "import pandas as pd\n",
27 | "import torch\n",
28 | "import torch.optim as optim\n",
29 | "import warnings\n",
30 | "warnings.filterwarnings('ignore')\n",
31 | "import matplotlib.pyplot as plt\n",
32 | "%matplotlib inline"
33 | ]
34 | },
35 | {
36 | "cell_type": "code",
37 | "execution_count": 6,
38 | "metadata": {},
39 | "outputs": [],
40 | "source": [
41 | "def kernel(ker, X1, X2, gamma):\n",
42 | " K = None\n",
43 | " if not ker or ker == 'primal':\n",
44 | " K = X1\n",
45 | " elif ker == 'linear':\n",
46 | " if X2 is not None:\n",
47 | " K = sklearn.metrics.pairwise.linear_kernel(\n",
48 | " np.asarray(X1).T, np.asarray(X2).T)\n",
49 | " else:\n",
50 | " K = sklearn.metrics.pairwise.linear_kernel(np.asarray(X1).T)\n",
51 | " elif ker == 'rbf':\n",
52 | " if X2 is not None:\n",
53 | " K = sklearn.metrics.pairwise.rbf_kernel(\n",
54 | " np.asarray(X1).T, np.asarray(X2).T, gamma)\n",
55 | " else:\n",
56 | " K = sklearn.metrics.pairwise.rbf_kernel(\n",
57 | " np.asarray(X1).T, None, gamma)\n",
58 | " return K\n",
59 | "\n",
60 | "\n",
61 | "class TCA:\n",
62 | " def __init__(self, kernel_type='primal', dim=30, lamb=1, gamma=1):\n",
63 | " '''\n",
64 | " Init func\n",
65 | " :param kernel_type: kernel, values: 'primal' | 'linear' | 'rbf'\n",
66 | " :param dim: dimension after transfer\n",
67 | " :param lamb: lambda value in equation\n",
68 | " :param gamma: kernel bandwidth for rbf kernel\n",
69 | " '''\n",
70 | " self.kernel_type = kernel_type\n",
71 | " self.dim = dim\n",
72 | " self.lamb = lamb\n",
73 | " self.gamma = gamma\n",
74 | "\n",
75 | " def fit(self, Xs, Xt):\n",
76 | " '''\n",
77 | " Transform Xs and Xt\n",
78 | " :param Xs: ns * n_feature, source feature\n",
79 | " :param Xt: nt * n_feature, target feature\n",
80 | " :return: Xs_new and Xt_new after TCA\n",
81 | " '''\n",
82 | " X = np.hstack((Xs.T, Xt.T))\n",
83 | " X /= np.linalg.norm(X, axis=0)\n",
84 | " m, n = X.shape\n",
85 | " ns, nt = len(Xs), len(Xt)\n",
86 | " e = np.vstack((1 / ns * np.ones((ns, 1)), -1 / nt * np.ones((nt, 1))))\n",
87 | " M = e * e.T\n",
88 | " M = M / np.linalg.norm(M, 'fro')\n",
89 | " H = np.eye(n) - 1 / n * np.ones((n, n))\n",
90 | " K = kernel(self.kernel_type, X, None, gamma=self.gamma)\n",
91 | " n_eye = m if self.kernel_type == 'primal' else n\n",
92 | " a, b = K @ M @ K.T + self.lamb * np.eye(n_eye), K @ H @ K.T\n",
93 | " w, V = scipy.linalg.eig(a, b)\n",
94 | " ind = np.argsort(w)\n",
95 | " A = V[:, ind[:self.dim]]\n",
96 | " Z = A.T @ K\n",
97 | " Z /= np.linalg.norm(Z, axis=0)\n",
98 | "\n",
99 | " Xs_new, Xt_new = Z[:, :ns].T, Z[:, ns:].T\n",
100 | " return Xs_new, Xt_new"
101 | ]
102 | },
103 | {
104 | "cell_type": "code",
105 | "execution_count": 2,
106 | "metadata": {},
107 | "outputs": [
108 | {
109 | "name": "stdout",
110 | "output_type": "stream",
111 | "text": [
112 | "load data...\n"
113 | ]
114 | }
115 | ],
116 | "source": [
117 | "# human heart\n",
118 | "# load data\n",
119 | "print('load data...')\n",
120 | "sc_data_processed = pd.read_csv('~/workspace/spatial_cluster/human_heart/sc_data_processed.csv', index_col=0)\n",
121 | "sc_meta_processed = pd.read_csv('~/workspace/spatial_cluster/human_heart/sc_meta_processed.csv', index_col=0)\n",
122 | "st_data_processed = pd.read_csv('~/workspace/spatial_cluster/human_heart/st_data_processed.csv', index_col=0)\n",
123 | "st_meta_processed = pd.read_csv('~/workspace/spatial_cluster/human_heart/st_meta_processed.csv', index_col=0)"
124 | ]
125 | },
126 | {
127 | "cell_type": "code",
128 | "execution_count": 12,
129 | "metadata": {},
130 | "outputs": [],
131 | "source": [
132 | "# tca\n",
133 | "obj = TCA(kernel_type='primal', dim=50, lamb=1, gamma=1)\n",
134 | "sc_new, st_new = obj.fit(Xs=np.array(sc_data_processed.T), Xt=np.array(st_data_processed.T))"
135 | ]
136 | },
137 | {
138 | "cell_type": "code",
139 | "execution_count": 16,
140 | "metadata": {},
141 | "outputs": [],
142 | "source": [
143 | "label = np.array(st_meta_processed[['new_x','new_y']])\n",
144 | "input_size = st_new.shape[1]\n",
145 | "hidden_size = 128\n",
146 | "output_size = 2\n",
147 | "batch_size = 16\n",
148 | "my_nn = torch.nn.Sequential(\n",
149 | " torch.nn.Linear(input_size, hidden_size),\n",
150 | " torch.nn.Sigmoid(),\n",
151 | " torch.nn.Linear(hidden_size, output_size),\n",
152 | ")\n",
153 | "cost = torch.nn.MSELoss(reduction='mean')\n",
154 | "optimizer = torch.optim.Adam(my_nn.parameters(), lr = 0.01)"
155 | ]
156 | },
157 | {
158 | "cell_type": "code",
159 | "execution_count": 18,
160 | "metadata": {},
161 | "outputs": [
162 | {
163 | "name": "stdout",
164 | "output_type": "stream",
165 | "text": [
166 | "0 118.557144\n",
167 | "100 7.5837355\n",
168 | "200 6.610284\n",
169 | "300 5.8897853\n",
170 | "400 5.2463884\n",
171 | "500 4.610996\n",
172 | "600 3.7047625\n",
173 | "700 2.787609\n",
174 | "800 2.7714293\n",
175 | "900 1.3030756\n"
176 | ]
177 | }
178 | ],
179 | "source": [
180 | "losses = []\n",
181 | "for i in range(1000):\n",
182 | " batch_loss = []\n",
183 | " for start in range(0, len(st_new), batch_size):\n",
184 | " end = start + batch_size if start + batch_size < len(st_new) else len(st_new)\n",
185 | " xx = torch.tensor(st_new[start:end], dtype = torch.float, requires_grad = True)\n",
186 | " yy = torch.tensor(label[start:end], dtype = torch.float, requires_grad = True)\n",
187 | " prediction = my_nn(xx)\n",
188 | " loss = cost(prediction, yy)\n",
189 | " optimizer.zero_grad()\n",
190 | " loss.backward(retain_graph=True)\n",
191 | " optimizer.step()\n",
192 | " batch_loss.append(loss.data.numpy())\n",
193 | " \n",
194 | " if i % 100==0:\n",
195 | " losses.append(np.mean(batch_loss))\n",
196 | " print(i, np.mean(batch_loss))"
197 | ]
198 | },
199 | {
200 | "cell_type": "code",
201 | "execution_count": 19,
202 | "metadata": {},
203 | "outputs": [],
204 | "source": [
205 | "predict = my_nn(torch.tensor(np.array(sc_new), dtype = torch.float, requires_grad = True)).data.numpy()"
206 | ]
207 | },
208 | {
209 | "cell_type": "code",
210 | "execution_count": 22,
211 | "metadata": {},
212 | "outputs": [],
213 | "source": [
214 | "pd.DataFrame(predict).to_csv('~/workspace/spatial_cluster/human_heart/pseudo_coords.csv')"
215 | ]
216 | },
217 | {
218 | "cell_type": "code",
219 | "execution_count": null,
220 | "metadata": {},
221 | "outputs": [],
222 | "source": []
223 | }
224 | ],
225 | "metadata": {
226 | "kernelspec": {
227 | "display_name": "scspace",
228 | "language": "python",
229 | "name": "scspace"
230 | },
231 | "language_info": {
232 | "codemirror_mode": {
233 | "name": "ipython",
234 | "version": 3
235 | },
236 | "file_extension": ".py",
237 | "mimetype": "text/x-python",
238 | "name": "python",
239 | "nbconvert_exporter": "python",
240 | "pygments_lexer": "ipython3",
241 | "version": "3.9.12"
242 | }
243 | },
244 | "nbformat": 4,
245 | "nbformat_minor": 4
246 | }
247 |
--------------------------------------------------------------------------------
/AnalysisPaper/scripts/figure3/human_heart_spatial_informed_clustering.R:
--------------------------------------------------------------------------------
1 | # this R script is for scSpace spatial-informed clustering step
2 |
3 | source('../scripts/utils.R')
4 | # parameters
5 | sc_data_file <- '~/workspace/spatial_cluster/human_heart/sc_data.csv'
6 | sc_meta_file <- '~/workspace/spatial_cluster/human_heart/sc_meta.csv'
7 | pseudo_coords_file <- '~/workspace/spatial_cluster/human_heart/pseudo_coords.csv'
8 | n_features <- 2000
9 | Ks <- 10
10 | Kg <- 20
11 |
12 | # load data
13 | print('load data...')
14 | sc_data <- read.csv(file = sc_data_file, row.names = 1)
15 | sc_meta <- read.csv(file = sc_meta_file, row.names = 1)
16 | pseudo_coords <- read.csv(file = pseudo_coords_file, row.names = 1)
17 |
18 | rownames(sc_meta) <- colnames(sc_data)
19 | sc_meta$pseudo_x <- pseudo_coords[,1]
20 | sc_meta$pseudo_y <- pseudo_coords[,2]
21 |
22 | sc_seu <- SeuratObject::CreateSeuratObject(sc_data, meta.data = sc_meta, verbose = FALSE)
23 | sc_seu <- NormalizeData(sc_seu, verbose = FALSE)
24 | sc_seu <- FindVariableFeatures(sc_seu, nfeatures = n_features, verbose = FALSE)
25 | sc_seu <- ScaleData(sc_seu)
26 | sc_seu <- RunPCA(sc_seu)
27 |
28 | sc_seu <- spa_cluster(
29 | sc_seu = sc_seu,
30 | coord_index = c('pseudo_x', 'pseudo_y'),
31 | Ks = 10,
32 | Kg = 20,
33 | res = 0.35
34 | )
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/AnalysisPaper/scripts/figure6/COVID19.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 1,
6 | "metadata": {},
7 | "outputs": [],
8 | "source": [
9 | "import numpy as np\n",
10 | "import scipy.io\n",
11 | "import scipy.linalg\n",
12 | "import sklearn.metrics\n",
13 | "from sklearn.neighbors import KNeighborsClassifier\n",
14 | "from sklearn.model_selection import train_test_split\n",
15 | "import pandas as pd\n",
16 | "\n",
17 | "import anndata as ad\n",
18 | "import scanpy as sc\n",
19 | "from sklearn.neighbors import KDTree\n",
20 | "import igraph as ig\n",
21 | "from scipy import sparse\n",
22 | "from sklearn.neighbors import KDTree\n",
23 | "from itertools import chain\n",
24 | "\n",
25 | "import numpy as np\n",
26 | "import pandas as pd\n",
27 | "import torch\n",
28 | "import torch.optim as optim\n",
29 | "import warnings\n",
30 | "warnings.filterwarnings('ignore')\n",
31 | "import matplotlib.pyplot as plt\n",
32 | "%matplotlib inline"
33 | ]
34 | },
35 | {
36 | "cell_type": "code",
37 | "execution_count": 2,
38 | "metadata": {},
39 | "outputs": [],
40 | "source": [
41 | "def kernel(ker, X1, X2, gamma):\n",
42 | " K = None\n",
43 | " if not ker or ker == 'primal':\n",
44 | " K = X1\n",
45 | " elif ker == 'linear':\n",
46 | " if X2 is not None:\n",
47 | " K = sklearn.metrics.pairwise.linear_kernel(\n",
48 | " np.asarray(X1).T, np.asarray(X2).T)\n",
49 | " else:\n",
50 | " K = sklearn.metrics.pairwise.linear_kernel(np.asarray(X1).T)\n",
51 | " elif ker == 'rbf':\n",
52 | " if X2 is not None:\n",
53 | " K = sklearn.metrics.pairwise.rbf_kernel(\n",
54 | " np.asarray(X1).T, np.asarray(X2).T, gamma)\n",
55 | " else:\n",
56 | " K = sklearn.metrics.pairwise.rbf_kernel(\n",
57 | " np.asarray(X1).T, None, gamma)\n",
58 | " return K\n",
59 | "\n",
60 | "\n",
61 | "class TCA:\n",
62 | " def __init__(self, kernel_type='primal', dim=30, lamb=1, gamma=1):\n",
63 | " '''\n",
64 | " Init func\n",
65 | " :param kernel_type: kernel, values: 'primal' | 'linear' | 'rbf'\n",
66 | " :param dim: dimension after transfer\n",
67 | " :param lamb: lambda value in equation\n",
68 | " :param gamma: kernel bandwidth for rbf kernel\n",
69 | " '''\n",
70 | " self.kernel_type = kernel_type\n",
71 | " self.dim = dim\n",
72 | " self.lamb = lamb\n",
73 | " self.gamma = gamma\n",
74 | "\n",
75 | " def fit(self, Xs, Xt):\n",
76 | " '''\n",
77 | " Transform Xs and Xt\n",
78 | " :param Xs: ns * n_feature, source feature\n",
79 | " :param Xt: nt * n_feature, target feature\n",
80 | " :return: Xs_new and Xt_new after TCA\n",
81 | " '''\n",
82 | " X = np.hstack((Xs.T, Xt.T))\n",
83 | " X /= np.linalg.norm(X, axis=0)\n",
84 | " m, n = X.shape\n",
85 | " ns, nt = len(Xs), len(Xt)\n",
86 | " e = np.vstack((1 / ns * np.ones((ns, 1)), -1 / nt * np.ones((nt, 1))))\n",
87 | " M = e * e.T\n",
88 | " M = M / np.linalg.norm(M, 'fro')\n",
89 | " H = np.eye(n) - 1 / n * np.ones((n, n))\n",
90 | " K = kernel(self.kernel_type, X, None, gamma=self.gamma)\n",
91 | " n_eye = m if self.kernel_type == 'primal' else n\n",
92 | " a, b = K @ M @ K.T + self.lamb * np.eye(n_eye), K @ H @ K.T\n",
93 | " w, V = scipy.linalg.eig(a, b)\n",
94 | " ind = np.argsort(w)\n",
95 | " A = V[:, ind[:self.dim]]\n",
96 | " Z = A.T @ K\n",
97 | " Z /= np.linalg.norm(Z, axis=0)\n",
98 | "\n",
99 | " Xs_new, Xt_new = Z[:, :ns].T, Z[:, ns:].T\n",
100 | " return Xs_new, Xt_new"
101 | ]
102 | },
103 | {
104 | "cell_type": "code",
105 | "execution_count": null,
106 | "metadata": {},
107 | "outputs": [
108 | {
109 | "name": "stdout",
110 | "output_type": "stream",
111 | "text": [
112 | "load data...\n",
113 | "tca...\n"
114 | ]
115 | }
116 | ],
117 | "source": [
118 | "# covid19 mdm\n",
119 | "# load data\n",
120 | "print('load data...')\n",
121 | "sc_data_processed = pd.read_csv('~/workspace/spatial_cluster/covid_19/sc_data_processed.csv', index_col=0)\n",
122 | "sc_meta_processed = pd.read_csv('~/workspace/spatial_cluster/covid_19/sc_meta_processed.csv', index_col=0)\n",
123 | "st_data_processed = pd.read_csv('~/workspace/spatial_cluster/covid_19/st_data_processed.csv', index_col=0)\n",
124 | "st_meta_processed = pd.read_csv('~/workspace/spatial_cluster/covid_19/st_meta_processed.csv', index_col=0)\n",
125 | "\n",
126 | "# tca\n",
127 | "print('tca...')\n",
128 | "obj = TCA(kernel_type='primal', dim=50, lamb=1, gamma=1)\n",
129 | "sc_new, st_new = obj.fit(Xs=np.array(sc_data_processed.T), Xt=np.array(st_data_processed.T))\n",
130 | "print('tca done.')"
131 | ]
132 | },
133 | {
134 | "cell_type": "code",
135 | "execution_count": 7,
136 | "metadata": {},
137 | "outputs": [
138 | {
139 | "name": "stdout",
140 | "output_type": "stream",
141 | "text": [
142 | "mlp...\n",
143 | "0 2169.201\n",
144 | "100 148.96654\n",
145 | "200 126.64259\n",
146 | "300 113.56344\n",
147 | "400 104.2271\n",
148 | "500 96.40067\n",
149 | "600 89.60366\n",
150 | "700 83.597404\n",
151 | "800 78.12729\n",
152 | "900 73.05979\n",
153 | "saving...\n"
154 | ]
155 | }
156 | ],
157 | "source": [
158 | "print('mlp...')\n",
159 | "label = np.array(st_meta_processed[['V3','V4']])\n",
160 | "input_size = st_new.shape[1]\n",
161 | "hidden_size = 128\n",
162 | "output_size = 2\n",
163 | "batch_size = 16\n",
164 | "my_nn = torch.nn.Sequential(\n",
165 | " torch.nn.Linear(input_size, hidden_size),\n",
166 | " torch.nn.Sigmoid(),\n",
167 | " torch.nn.Linear(hidden_size, output_size),\n",
168 | ")\n",
169 | "cost = torch.nn.MSELoss(reduction='mean')\n",
170 | "optimizer = torch.optim.Adam(my_nn.parameters(), lr = 0.001)\n",
171 | "\n",
172 | "losses = []\n",
173 | "for i in range(1000):\n",
174 | " batch_loss = []\n",
175 | " for start in range(0, len(st_new), batch_size):\n",
176 | " end = start + batch_size if start + batch_size < len(st_new) else len(st_new)\n",
177 | " xx = torch.tensor(st_new[start:end], dtype = torch.float, requires_grad = True)\n",
178 | " yy = torch.tensor(label[start:end], dtype = torch.float, requires_grad = True)\n",
179 | " prediction = my_nn(xx)\n",
180 | " loss = cost(prediction, yy)\n",
181 | " optimizer.zero_grad()\n",
182 | " loss.backward(retain_graph=True)\n",
183 | " optimizer.step()\n",
184 | " batch_loss.append(loss.data.numpy())\n",
185 | " \n",
186 | " if i % 100==0:\n",
187 | " losses.append(np.mean(batch_loss))\n",
188 | " print(i, np.mean(batch_loss))\n",
189 | "\n",
190 | "print('saving...') \n",
191 | "predict = my_nn(torch.tensor(np.array(sc_new), dtype = torch.float, requires_grad = True)).data.numpy()\n",
192 | "pd.DataFrame(predict).to_csv('~/workspace/spatial_cluster/covid_19/pseudo_coords.csv')"
193 | ]
194 | },
195 | {
196 | "cell_type": "code",
197 | "execution_count": null,
198 | "metadata": {},
199 | "outputs": [],
200 | "source": []
201 | }
202 | ],
203 | "metadata": {
204 | "kernelspec": {
205 | "display_name": "scspace",
206 | "language": "python",
207 | "name": "scspace"
208 | },
209 | "language_info": {
210 | "codemirror_mode": {
211 | "name": "ipython",
212 | "version": 3
213 | },
214 | "file_extension": ".py",
215 | "mimetype": "text/x-python",
216 | "name": "python",
217 | "nbconvert_exporter": "python",
218 | "pygments_lexer": "ipython3",
219 | "version": "3.9.12"
220 | }
221 | },
222 | "nbformat": 4,
223 | "nbformat_minor": 4
224 | }
225 |
--------------------------------------------------------------------------------
/AnalysisPaper/scripts/figure6/MDM_spatial_informed_clustering.R:
--------------------------------------------------------------------------------
1 | # this R script is for scSpace spatial-informed clustering step
2 |
3 | source('../scripts/utils.R')
4 | # parameters
5 | sc_data_file <- '~/workspace/scSpace/data/[9]human_covid19/original_data/sc_data_sampled.csv'
6 | sc_meta_file <- '~/workspace/scSpace/data/[9]human_covid19/original_data/sc_meta_sampled.csv'
7 | pseudo_coords_file <- '~/workspace/scSpace/data/[9]human_covid19/pseudo_space/pseudo_coords.csv'
8 | n_features <- 2000
9 | Ks <- 10
10 | Kg <- 20
11 |
12 | # load data
13 | print('load data...')
14 | sc_data <- read.csv(file = sc_data_file, row.names = 1)
15 | sc_meta <- read.csv(file = sc_meta_file, row.names = 1)
16 | pseudo_coords <- read.csv(file = pseudo_coords_file, row.names = 1)
17 |
18 | rownames(sc_meta) <- colnames(sc_data)
19 | sc_meta$pseudo_x <- pseudo_coords[,1]
20 | sc_meta$pseudo_y <- pseudo_coords[,2]
21 |
22 | mdm_meta <- sc_meta[sc_meta$cell_type_fine == 'Monocyte-derived macrophages' | sc_meta$cell_type_fine == 'Transitioning MDM', ]
23 | mdm_data <- sc_data[, rownames(mdm_meta)]
24 | sc_seu <- SeuratObject::CreateSeuratObject(mdm_data, meta.data = mdm_meta, verbose = FALSE)
25 | sc_seu <- FindVariableFeatures(sc_seu, nfeatures = n_features, verbose = FALSE)
26 | sc_seu <- ScaleData(sc_seu)
27 | sc_seu <- RunPCA(sc_seu)
28 |
29 | sc_seu <- spa_cluster(
30 | sc_seu = sc_seu,
31 | coord_index = c('pseudo_x', 'pseudo_y'),
32 | Ks = 10,
33 | Kg = 20,
34 | res = 0.6
35 | )
36 |
--------------------------------------------------------------------------------
/AnalysisPaper/scripts/utils.R:
--------------------------------------------------------------------------------
1 | # custom functions for downstream analysis
2 |
3 |
4 | run_RCTD <- function(sc_meta,
5 | sc_data,
6 | st_meta,
7 | st_data,
8 | celltype_index){
9 | ### Create the Reference object
10 | cell_types <- as.factor(sc_meta[[celltype_index]]); names(cell_types) <- colnames(sc_data)
11 | reference <- Reference(sc_data, cell_types, require_int = FALSE)
12 |
13 | coords <- data.frame(x = st_meta$xcoord, y = st_meta$ycoord)
14 | rownames(coords) <- colnames(st_data)
15 |
16 | ### Create SpatialRNA object
17 | puck <- SpatialRNA(coords, st_data, require_int = FALSE)
18 |
19 | myRCTD <- create.RCTD(puck, reference, CELL_MIN_INSTANCE = 5)
20 | myRCTD <- run.RCTD(myRCTD, doublet_mode = 'full')
21 | results <- myRCTD@results
22 | # normalize the cell type proportions to sum to 1.
23 | norm_weights <- normalize_weights(results$weights)
24 | norm_weights <- data.frame(as.matrix(norm_weights))
25 |
26 | return(norm_weights)
27 | }
28 |
29 |
30 | run_Seurat <- function(sc_meta,
31 | sc_data,
32 | res){
33 | sc_seu <- CreateSeuratObject(sc_data, meta.data = sc_meta, verbose = FALSE)
34 | sc_seu <- NormalizeData(sc_seu, verbose = FALSE)
35 | sc_seu <- FindVariableFeatures(sc_seu, nfeatures = 2000, verbose = FALSE)
36 | sc_seu <- ScaleData(sc_seu, features = rownames(sc_seu), verbose = FALSE)
37 | sc_seu <- RunPCA(sc_seu, verbose = FALSE)
38 | sc_seu <- RunTSNE(sc_seu, dims = 1:20, verbose = FALSE)
39 | sc_seu <- FindNeighbors(sc_seu)
40 | sc_seu <- FindClusters(sc_seu, resolution = res)
41 | return(sc_seu)
42 | }
43 |
44 |
45 | cal_dist <- function(meta,
46 | coord_index,
47 | group_by,
48 | selected_type,
49 | ignore_select_type = FALSE){
50 | dist <- as.matrix(dist(meta[, coord_index]))
51 |
52 | ct_type <- sort(unique(meta[[group_by]]))
53 |
54 | if(ignore_select_type){
55 | ct_type <- setdiff(ct_type, selected_type)
56 | }
57 |
58 | select_ct_index <- which(meta[[group_by]] == selected_type)
59 |
60 | pseudo_dist_table <- data.frame()
61 |
62 | message('Beginning normalized distance calculating...')
63 | pb <- progress::progress_bar$new(format = ' Calculating [:bar] :percent eta: :eta',
64 | total = length(ct_type), clear = FALSE, width = 60,
65 | complete = "+", incomplete = "-")
66 |
67 | # dist
68 | for (i in ct_type) {
69 | ct_index <- which(meta[[group_by]] == i)
70 | dist_list <- c()
71 | if(i == selected_type){
72 | for (j in ct_index) {
73 | col_index <- j
74 | dist_list <- c(dist_list, dist[ct_index, col_index])
75 | ct_index <- setdiff(ct_index, col_index)
76 | }
77 | }
78 | else{
79 | for (j in select_ct_index) {
80 | col_index <- j
81 | dist_list <- c(dist_list, dist[ct_index, col_index])
82 | }
83 | }
84 |
85 | dist_table <- data.frame(dist = dist_list,
86 | group = rep(paste0(selected_type, '_', i), length(dist_list)))
87 |
88 | pseudo_dist_table <- rbind(pseudo_dist_table, dist_table)
89 |
90 | pb$tick()
91 | }
92 | print('Normalized distance calculating done.')
93 |
94 | pseudo_dist_table$dist <- pseudo_dist_table$dist / max(pseudo_dist_table$dist)
95 | return(pseudo_dist_table)
96 |
97 | }
98 |
99 |
100 | plotEnrichment_new <- function(pathway, stats,
101 | gseaParam=1,
102 | ticksSize=0.2) {
103 |
104 | rnk <- rank(-stats)
105 | ord <- order(rnk)
106 |
107 | statsAdj <- stats[ord]
108 | statsAdj <- sign(statsAdj) * (abs(statsAdj) ^ gseaParam)
109 | statsAdj <- statsAdj / max(abs(statsAdj))
110 |
111 | pathway <- unname(as.vector(na.omit(match(pathway, names(statsAdj)))))
112 | pathway <- sort(pathway)
113 |
114 | gseaRes <- calcGseaStat(statsAdj, selectedStats = pathway,
115 | returnAllExtremes = TRUE)
116 |
117 | bottoms <- gseaRes$bottoms
118 | tops <- gseaRes$tops
119 |
120 | n <- length(statsAdj)
121 | xs <- as.vector(rbind(pathway - 1, pathway))
122 | ys <- as.vector(rbind(bottoms, tops))
123 | toPlot <- data.frame(x=c(0, xs, n + 1), y=c(0, ys, 0))
124 |
125 | diff <- (max(tops) - min(bottoms)) / 8
126 |
127 | # Getting rid of NOTEs
128 | x=y=NULL
129 | g <- ggplot(toPlot, aes(x=x, y=y)) +
130 | # geom_point(color="blue", size=0.1) +
131 | # geom_hline(yintercept=max(tops), colour="red", linetype="dashed") +
132 | # geom_hline(yintercept=min(bottoms), colour="red", linetype="dashed") +
133 | geom_hline(yintercept=0, colour="black") +
134 | geom_line(color="#059669", size = 1.5) + theme_bw() +
135 | geom_segment(data=data.frame(x=pathway),
136 | mapping=aes(x=x, y=-diff/2,
137 | xend=x, yend=diff/2),
138 | size=ticksSize) +
139 |
140 | theme(panel.border=element_blank(),
141 | panel.grid.minor=element_blank()) +
142 |
143 | labs(x="rank", y="enrichment score")
144 | g
145 | }
146 |
147 |
148 | run_DRSC <- function(data,
149 | meta,
150 | cluster_num){
151 |
152 |
153 | seu <- CreateSeuratObject(data, meta.data = meta)
154 | seu <- NormalizeData(seu, verbose = F)
155 | # choose 480 spatially variable features
156 | seu <- FindSVGs(seu, nfeatures = 480)
157 | ### Given K
158 | seu <- DR.SC(seu, K=cluster_num, platform = 'seqfish', verbose=F)
159 |
160 | res <- seu@meta.data
161 |
162 | return(res)
163 | }
164 |
165 |
166 | run_BayesSpace <- function(data,
167 | meta,
168 | cluster_num){
169 |
170 |
171 | sce <- SingleCellExperiment(assays=list(counts=as(as.matrix(data), "dgCMatrix")), colData=meta)
172 |
173 | set.seed(102)
174 | sce <- spatialPreprocess(sce, platform="Visium",
175 | n.PCs=15, n.HVGs=2000, log.normalize=TRUE)
176 | set.seed(149)
177 | sce <- spatialCluster(sce, q=cluster_num, platform="Visium", d=15,
178 | init.method="mclust", model="t", gamma=2,
179 | nrep=10000, burn.in=100,
180 | save.chain=TRUE)
181 |
182 | res <- data.frame(sce@colData)
183 |
184 | return(res)
185 | }
186 |
187 |
188 | # evaluate clustering results in benchmarking step
189 | eva_function <- function(clu_obj,
190 | sim_id,
191 | method_choose,
192 | all_cluster = TRUE,
193 | select_spatial_cluster = NULL){
194 | if(all_cluster){
195 | print('calculating all clusters...')
196 | meta <- clu_obj
197 | }
198 | else{
199 | print('calculating spatial clustering...')
200 | meta <- clu_obj
201 | meta <- meta[meta$Group %in% select_spatial_cluster, ]
202 | }
203 |
204 | meta[[method_choose]] <- as.factor(meta[[method_choose]])
205 |
206 | ari <- mclust::adjustedRandIndex(meta$Group, meta[[method_choose]])
207 | nmi <- NMI::NMI(data.frame(cell = 1:nrow(meta), clu = meta$Group),
208 | data.frame(cell = 1:nrow(meta), clu = meta[[method_choose]]))$value
209 |
210 |
211 |
212 | res_obj <- data.frame(
213 | sim = sim_id,
214 | method = method_choose,
215 | ari = ari,
216 | nmi = nmi)
217 |
218 | return(res_obj)
219 | }
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 | # old spatial-informed clustering for scSpace
229 | spa_cluster <- function(sc_seu,
230 | coord_index,
231 | seeds = 100,
232 | res,
233 | Ks,
234 | Kg){
235 | knn_idx <- data.frame(BiocNeighbors::findKNN(sc_seu@meta.data[,coord_index], k = Ks)$index)
236 | N <- nrow(knn_idx)
237 | W <- matrix(0, N, N)
238 |
239 | diag(W) <- 1
240 | for (i in 1:nrow(W)) {
241 | W[i, as.numeric(knn_idx[i,])] <- 1
242 | }
243 |
244 | colnames(W) <- rownames(W) <- colnames(sc_seu)
245 |
246 | sc_pca_ori <- sc_seu@reductions$pca@cell.embeddings
247 |
248 |
249 | # create gene expression k-nearest neighbors
250 | knn_idx <- BiocNeighbors::findKNN(sc_pca_ori, k = Kg)$index
251 |
252 | # create weights from binary adjacency matrix W
253 | sp_graph <- igraph::graph_from_adjacency_matrix(W)
254 | sp_graph <- igraph::simplify(sp_graph)
255 | sp_weight <- matrix(ncol = ncol(knn_idx), nrow = nrow(knn_idx))
256 | for (i in 1:nrow(knn_idx)) {
257 | to_idx <- as.numeric(knn_idx[i,])
258 | sp_weight[i,] <- igraph::distances(sp_graph, rownames(W)[i], colnames(W)[to_idx])
259 | }
260 |
261 | weight <- 1/(0 + as.vector(sp_weight)) + 0
262 |
263 | # graph-based clustering with spatial weights
264 | df <- data.frame(from = rep(1:nrow(knn_idx), Kg),
265 | to = as.vector(knn_idx),
266 | weight = weight)
267 |
268 | g <- igraph::graph_from_data_frame(df, directed = FALSE)
269 | g <- igraph::simplify(g)
270 |
271 | set.seed(seeds)
272 | cluster <- leidenAlg::leiden.community(g, resolution = res, n.iterations = 2)
273 | sc_seu$scSpace <- cluster$membership
274 |
275 | return(sc_seu)
276 | }
277 |
278 |
279 |
280 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU General Public License is a free, copyleft license for
11 | software and other kinds of works.
12 |
13 | The licenses for most software and other practical works are designed
14 | to take away your freedom to share and change the works. By contrast,
15 | the GNU General Public License is intended to guarantee your freedom to
16 | share and change all versions of a program--to make sure it remains free
17 | software for all its users. We, the Free Software Foundation, use the
18 | GNU General Public License for most of our software; it applies also to
19 | any other work released this way by its authors. You can apply it to
20 | your programs, too.
21 |
22 | When we speak of free software, we are referring to freedom, not
23 | price. Our General Public Licenses are designed to make sure that you
24 | have the freedom to distribute copies of free software (and charge for
25 | them if you wish), that you receive source code or can get it if you
26 | want it, that you can change the software or use pieces of it in new
27 | free programs, and that you know you can do these things.
28 |
29 | To protect your rights, we need to prevent others from denying you
30 | these rights or asking you to surrender the rights. Therefore, you have
31 | certain responsibilities if you distribute copies of the software, or if
32 | you modify it: responsibilities to respect the freedom of others.
33 |
34 | For example, if you distribute copies of such a program, whether
35 | gratis or for a fee, you must pass on to the recipients the same
36 | freedoms that you received. You must make sure that they, too, receive
37 | or can get the source code. And you must show them these terms so they
38 | know their rights.
39 |
40 | Developers that use the GNU GPL protect your rights with two steps:
41 | (1) assert copyright on the software, and (2) offer you this License
42 | giving you legal permission to copy, distribute and/or modify it.
43 |
44 | For the developers' and authors' protection, the GPL clearly explains
45 | that there is no warranty for this free software. For both users' and
46 | authors' sake, the GPL requires that modified versions be marked as
47 | changed, so that their problems will not be attributed erroneously to
48 | authors of previous versions.
49 |
50 | Some devices are designed to deny users access to install or run
51 | modified versions of the software inside them, although the manufacturer
52 | can do so. This is fundamentally incompatible with the aim of
53 | protecting users' freedom to change the software. The systematic
54 | pattern of such abuse occurs in the area of products for individuals to
55 | use, which is precisely where it is most unacceptable. Therefore, we
56 | have designed this version of the GPL to prohibit the practice for those
57 | products. If such problems arise substantially in other domains, we
58 | stand ready to extend this provision to those domains in future versions
59 | of the GPL, as needed to protect the freedom of users.
60 |
61 | Finally, every program is threatened constantly by software patents.
62 | States should not allow patents to restrict development and use of
63 | software on general-purpose computers, but in those that do, we wish to
64 | avoid the special danger that patents applied to a free program could
65 | make it effectively proprietary. To prevent this, the GPL assures that
66 | patents cannot be used to render the program non-free.
67 |
68 | The precise terms and conditions for copying, distribution and
69 | modification follow.
70 |
71 | TERMS AND CONDITIONS
72 |
73 | 0. Definitions.
74 |
75 | "This License" refers to version 3 of the GNU General Public License.
76 |
77 | "Copyright" also means copyright-like laws that apply to other kinds of
78 | works, such as semiconductor masks.
79 |
80 | "The Program" refers to any copyrightable work licensed under this
81 | License. Each licensee is addressed as "you". "Licensees" and
82 | "recipients" may be individuals or organizations.
83 |
84 | To "modify" a work means to copy from or adapt all or part of the work
85 | in a fashion requiring copyright permission, other than the making of an
86 | exact copy. The resulting work is called a "modified version" of the
87 | earlier work or a work "based on" the earlier work.
88 |
89 | A "covered work" means either the unmodified Program or a work based
90 | on the Program.
91 |
92 | To "propagate" a work means to do anything with it that, without
93 | permission, would make you directly or secondarily liable for
94 | infringement under applicable copyright law, except executing it on a
95 | computer or modifying a private copy. Propagation includes copying,
96 | distribution (with or without modification), making available to the
97 | public, and in some countries other activities as well.
98 |
99 | To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies. Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 |
103 | An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License. If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 |
112 | 1. Source Code.
113 |
114 | The "source code" for a work means the preferred form of the work
115 | for making modifications to it. "Object code" means any non-source
116 | form of a work.
117 |
118 | A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 |
123 | The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form. A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 |
134 | The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities. However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work. For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 |
147 | The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 |
151 | The Corresponding Source for a work in source code form is that
152 | same work.
153 |
154 | 2. Basic Permissions.
155 |
156 | All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met. This License explicitly affirms your unlimited
159 | permission to run the unmodified Program. The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work. This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 |
164 | You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force. You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright. Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 |
175 | Conveying under any other circumstances is permitted solely under
176 | the conditions stated below. Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 |
179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 |
181 | No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 |
187 | When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 |
195 | 4. Conveying Verbatim Copies.
196 |
197 | You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 |
205 | You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 |
208 | 5. Conveying Modified Source Versions.
209 |
210 | You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 |
214 | a) The work must carry prominent notices stating that you modified
215 | it, and giving a relevant date.
216 |
217 | b) The work must carry prominent notices stating that it is
218 | released under this License and any conditions added under section
219 | 7. This requirement modifies the requirement in section 4 to
220 | "keep intact all notices".
221 |
222 | c) You must license the entire work, as a whole, under this
223 | License to anyone who comes into possession of a copy. This
224 | License will therefore apply, along with any applicable section 7
225 | additional terms, to the whole of the work, and all its parts,
226 | regardless of how they are packaged. This License gives no
227 | permission to license the work in any other way, but it does not
228 | invalidate such permission if you have separately received it.
229 |
230 | d) If the work has interactive user interfaces, each must display
231 | Appropriate Legal Notices; however, if the Program has interactive
232 | interfaces that do not display Appropriate Legal Notices, your
233 | work need not make them do so.
234 |
235 | A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit. Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 |
245 | 6. Conveying Non-Source Forms.
246 |
247 | You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 |
252 | a) Convey the object code in, or embodied in, a physical product
253 | (including a physical distribution medium), accompanied by the
254 | Corresponding Source fixed on a durable physical medium
255 | customarily used for software interchange.
256 |
257 | b) Convey the object code in, or embodied in, a physical product
258 | (including a physical distribution medium), accompanied by a
259 | written offer, valid for at least three years and valid for as
260 | long as you offer spare parts or customer support for that product
261 | model, to give anyone who possesses the object code either (1) a
262 | copy of the Corresponding Source for all the software in the
263 | product that is covered by this License, on a durable physical
264 | medium customarily used for software interchange, for a price no
265 | more than your reasonable cost of physically performing this
266 | conveying of source, or (2) access to copy the
267 | Corresponding Source from a network server at no charge.
268 |
269 | c) Convey individual copies of the object code with a copy of the
270 | written offer to provide the Corresponding Source. This
271 | alternative is allowed only occasionally and noncommercially, and
272 | only if you received the object code with such an offer, in accord
273 | with subsection 6b.
274 |
275 | d) Convey the object code by offering access from a designated
276 | place (gratis or for a charge), and offer equivalent access to the
277 | Corresponding Source in the same way through the same place at no
278 | further charge. You need not require recipients to copy the
279 | Corresponding Source along with the object code. If the place to
280 | copy the object code is a network server, the Corresponding Source
281 | may be on a different server (operated by you or a third party)
282 | that supports equivalent copying facilities, provided you maintain
283 | clear directions next to the object code saying where to find the
284 | Corresponding Source. Regardless of what server hosts the
285 | Corresponding Source, you remain obligated to ensure that it is
286 | available for as long as needed to satisfy these requirements.
287 |
288 | e) Convey the object code using peer-to-peer transmission, provided
289 | you inform other peers where the object code and Corresponding
290 | Source of the work are being offered to the general public at no
291 | charge under subsection 6d.
292 |
293 | A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 |
297 | A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling. In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage. For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product. A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 |
310 | "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source. The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 |
318 | If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information. But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 |
329 | The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed. Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 |
337 | Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 |
343 | 7. Additional Terms.
344 |
345 | "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law. If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 |
354 | When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it. (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.) You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 |
361 | Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 |
365 | a) Disclaiming warranty or limiting liability differently from the
366 | terms of sections 15 and 16 of this License; or
367 |
368 | b) Requiring preservation of specified reasonable legal notices or
369 | author attributions in that material or in the Appropriate Legal
370 | Notices displayed by works containing it; or
371 |
372 | c) Prohibiting misrepresentation of the origin of that material, or
373 | requiring that modified versions of such material be marked in
374 | reasonable ways as different from the original version; or
375 |
376 | d) Limiting the use for publicity purposes of names of licensors or
377 | authors of the material; or
378 |
379 | e) Declining to grant rights under trademark law for use of some
380 | trade names, trademarks, or service marks; or
381 |
382 | f) Requiring indemnification of licensors and authors of that
383 | material by anyone who conveys the material (or modified versions of
384 | it) with contractual assumptions of liability to the recipient, for
385 | any liability that these contractual assumptions directly impose on
386 | those licensors and authors.
387 |
388 | All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10. If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term. If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 |
398 | If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 |
403 | Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 |
407 | 8. Termination.
408 |
409 | You may not propagate or modify a covered work except as expressly
410 | provided under this License. Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 |
415 | However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 |
422 | Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 |
429 | Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License. If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 |
435 | 9. Acceptance Not Required for Having Copies.
436 |
437 | You are not required to accept this License in order to receive or
438 | run a copy of the Program. Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance. However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work. These actions infringe copyright if you do
443 | not accept this License. Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 |
446 | 10. Automatic Licensing of Downstream Recipients.
447 |
448 | Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License. You are not responsible
451 | for enforcing compliance by third parties with this License.
452 |
453 | An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations. If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 |
463 | You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License. For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 |
471 | 11. Patents.
472 |
473 | A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based. The
475 | work thus licensed is called the contributor's "contributor version".
476 |
477 | A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version. For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 |
487 | Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 |
492 | In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement). To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 |
499 | If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients. "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 |
513 | If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 |
521 | A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License. You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 |
536 | Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 |
540 | 12. No Surrender of Others' Freedom.
541 |
542 | If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License. If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all. For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 |
552 | 13. Use with the GNU Affero General Public License.
553 |
554 | Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work. The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 |
563 | 14. Revised Versions of this License.
564 |
565 | The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time. Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 |
570 | Each version is given a distinguishing version number. If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation. If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 |
579 | If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 |
584 | Later license versions may give you additional or different
585 | permissions. However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 |
589 | 15. Disclaimer of Warranty.
590 |
591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 |
600 | 16. Limitation of Liability.
601 |
602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 |
612 | 17. Interpretation of Sections 15 and 16.
613 |
614 | If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 |
621 | END OF TERMS AND CONDITIONS
622 |
623 | How to Apply These Terms to Your New Programs
624 |
625 | If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 |
629 | To do so, attach the following notices to the program. It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 |
634 |
635 | Copyright (C)
636 |
637 | This program is free software: you can redistribute it and/or modify
638 | it under the terms of the GNU General Public License as published by
639 | the Free Software Foundation, either version 3 of the License, or
640 | (at your option) any later version.
641 |
642 | This program is distributed in the hope that it will be useful,
643 | but WITHOUT ANY WARRANTY; without even the implied warranty of
644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 | GNU General Public License for more details.
646 |
647 | You should have received a copy of the GNU General Public License
648 | along with this program. If not, see .
649 |
650 | Also add information on how to contact you by electronic and paper mail.
651 |
652 | If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 |
655 | Copyright (C)
656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 | This is free software, and you are welcome to redistribute it
658 | under certain conditions; type `show c' for details.
659 |
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License. Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 |
664 | You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | .
668 |
669 | The GNU General Public License does not permit incorporating your program
670 | into proprietary programs. If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library. If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License. But first, please read
674 | .
675 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # scSpace v1.0.0
2 |
3 | ## Reconstruction of cell pseudo space from single-cell RNA sequencing data
4 |
5 | [](https://www.python.org/) [](https://doi.org/10.5281/zenodo.7790754)
6 |
7 | scSpace (**s**ingle-**c**ell and **s**patial **p**osition **a**ssociated **c**o-**e**mbeddings) is an integrative algorithm that integrates spatial transcriptome data to reconstruct spatial associations of single cells within scRNA-seq data. Using [transfer component analysis (TCA)](https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=5640675&tag=1), scSpace could extract the characteristic matrixes of spatial transcriptomics and scRNA-seq, and project single cells into a pseudo space via a [multiple layer perceptron (MLP)](https://en.wikipedia.org/wiki/Multilayer_perceptron) model, so that gene expression and spatial weight of cells can be embedded jointly for the further cell typing with higher accuracy and precision.
8 |
9 | 
10 |
11 | Code for generating the figures in this study can be found [here](AnalysisPaper).
12 |
13 | ## Requirements and Installation
14 | [](https://pypi.org/project/numpy/) [](https://pypi.org/project/pandas/) [](https://pypi.org/project/scikit-learn/) [](https://pypi.org/project/scipy/) [](https://github.com/scverse/scanpy) [](https://pypi.org/project/matplotlib/) [](https://pypi.org/project/igraph/) [](https://pypi.org/project/leidenalg/) [](https://pypi.org/project/tqdm/)
15 |
16 | ### Create and activate Python environment
17 | For scSpace, the python version need is over 3.8. If you have installed Python3.6 or Python3.7, consider installing Anaconda, and then you can create a new environment.
18 | ```
19 | conda create -n scspace python=3.8
20 | conda activate scspace
21 | ```
22 | ### Install pytorch
23 | The version of pytorch should be suitable to the CUDA version of your machine. You can find the appropriate version on the [PyTorch website](https://pytorch.org/get-started/locally/).
24 | Here is an example with CUDA11.6:
25 | ```
26 | pip install torch --extra-index-url https://download.pytorch.org/whl/cu116
27 | ```
28 | ### Install other requirements
29 | ```
30 | cd scSpace-master
31 | pip install -r requirements.txt
32 | ```
33 | ### Install scSpace
34 | ```
35 | python setup.py build
36 | python setup.py install
37 | ```
38 |
39 | ## Quick Start
40 | To use scSpace we require five formatted `.csv` files as input (i.e. read in by pandas). We have included a toy dataset
41 | in the [vignettes/data folder](vignettes/data) of this repository as examples to show how to use scSpace:
42 | * [Demonstration of scSpace on demo dataset](vignettes/demo.ipynb)
43 |
44 |
45 | ## Tutorials
46 | Additional step-by-step tutorials now available! Preprocessed datasets used can be downloaded from [Google Drive](https://drive.google.com/drive/folders/1a0dPYYFITrhmMhSeNc1HSWLfx6-bDy65?usp=sharing).
47 |
48 | 1. [Spatial reconstruction of human DLPFC spatial transcriptomics data](vignettes/DLPFC_slice151674.ipynb)
49 |
50 | 2. [Spatial reconstruction of human SCC spatial transcriptomics data](vignettes/SCC_p2.ipynb)
51 |
52 | 3. [Spatial reconstruction of mouse intestine scRNA-seq data](vignettes/intestines.ipynb)
53 |
54 | 4. [Spatial analysis of T cells subpopulations in melanoma](vignettes/melanoma.ipynb)
55 |
56 |
57 | ## About
58 | scSpace was developed by Jie Liao and Jingyang Qian. Should you have any questions, please contact Jie Liao at liaojie@zju.edu.cn, or Jingyang Qian at qianjingyang@zju.edu.cn
59 |
60 | ## References
61 | Qian, J., Liao, J., Liu, Z. et al. Reconstruction of the cell pseudo-space from single-cell RNA sequencing data with scSpace. Nat Commun 14, 2484 (2023). [https://doi.org/10.1038/s41467-023-38121-4](https://doi.org/10.1038/s41467-023-38121-4)
62 |
--------------------------------------------------------------------------------
/images/workflow.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ZJUFanLab/scSpace/ab7cfff007289873fa38a06e528660772b235393/images/workflow.jpg
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | igraph==0.10.2
2 | leidenalg==0.9.0
3 | numpy==1.23.4
4 | pandas==1.5.0
5 | scanpy==1.9.1
6 | matplotlib==3.6.3
7 | scikit-learn==1.1.2
8 | scipy==1.9.2
9 | tqdm==4.64.1
10 | scikit-misc==0.1.4
11 |
--------------------------------------------------------------------------------
/scSpace/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 | # @Time : 2022/7/20 9:41 上午
4 | # @Author : qjy
5 | # @Site :
6 | # @File : __init__.py.py
7 | # @Software: PyCharm
8 |
9 |
10 | __author__ = "Jingyang Qian"
11 | __email__ = "qianjingyang@zju.edu.cn"
12 |
13 | from .utils import *
14 | from .scspace import *
15 | from .models import *
16 |
--------------------------------------------------------------------------------
/scSpace/models.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import scipy.io
3 | import scipy.linalg
4 | import sklearn.metrics
5 | from torch import nn
6 |
7 |
8 | def kernel(ker, X1, X2, gamma):
9 | K = None
10 | if not ker or ker == 'primal':
11 | K = X1
12 | elif ker == 'linear':
13 | if X2 is not None:
14 | K = sklearn.metrics.pairwise.linear_kernel(
15 | np.asarray(X1).T, np.asarray(X2).T)
16 | else:
17 | K = sklearn.metrics.pairwise.linear_kernel(np.asarray(X1).T)
18 | elif ker == 'rbf':
19 | if X2 is not None:
20 | K = sklearn.metrics.pairwise.rbf_kernel(
21 | np.asarray(X1).T, np.asarray(X2).T, gamma)
22 | else:
23 | K = sklearn.metrics.pairwise.rbf_kernel(
24 | np.asarray(X1).T, None, gamma)
25 | return K
26 |
27 |
28 | class TCA:
29 | def __init__(self, kernel_type='primal', dim=30, lamb=1, gamma=1):
30 | '''
31 | Init func
32 | :param kernel_type: kernel, values: 'primal' | 'linear' | 'rbf'
33 | :param dim: dimension after transfer
34 | :param lamb: lambda value in equation
35 | :param gamma: kernel bandwidth for rbf kernel
36 | '''
37 | self.kernel_type = kernel_type
38 | self.dim = dim
39 | self.lamb = lamb
40 | self.gamma = gamma
41 |
42 | def fit(self, Xs, Xt):
43 | '''
44 | Transform Xs and Xt
45 | :param Xs: ns * n_feature, source feature
46 | :param Xt: nt * n_feature, target feature
47 | :return: Xs_new and Xt_new after TCA
48 | '''
49 | X = np.hstack((Xs.T, Xt.T))
50 | X /= np.linalg.norm(X, axis=0)
51 | m, n = X.shape
52 | ns, nt = len(Xs), len(Xt)
53 | e = np.vstack((1 / ns * np.ones((ns, 1)), -1 / nt * np.ones((nt, 1))))
54 | M = e * e.T
55 | M = M / np.linalg.norm(M, 'fro')
56 | H = np.eye(n) - 1 / n * np.ones((n, n))
57 | K = kernel(self.kernel_type, X, None, gamma=self.gamma)
58 | n_eye = m if self.kernel_type == 'primal' else n
59 | a, b = K @ M @ K.T + self.lamb * np.eye(n_eye), K @ H @ K.T
60 | w, V = scipy.linalg.eig(a, b)
61 | ind = np.argsort(w)
62 | A = V[:, ind[:self.dim]]
63 | Z = A.T @ K
64 | Z /= np.linalg.norm(Z, axis=0)
65 |
66 | Xs_new, Xt_new = Z[:, :ns].T, Z[:, ns:].T
67 | return Xs_new, Xt_new
68 |
69 |
70 | activation_dict = {
71 | 'relu': nn.ReLU,
72 | 'sigmoid': nn.Sigmoid
73 | }
74 |
75 |
76 | class sample_MLPEncoder(nn.Module):
77 | """sample MLPEncoder encoder model for scSpace."""
78 |
79 | def __init__(self, input_size, common_size, hidden_size, activation):
80 | """Init MLP encoder."""
81 | super(sample_MLPEncoder, self).__init__()
82 | self.restored = False
83 | common_size = common_size
84 | self.linear = nn.Sequential(
85 | nn.Linear(input_size, hidden_size),
86 | activation_dict[activation](),
87 | nn.Linear(hidden_size, common_size)
88 | )
89 |
90 | def forward(self, x):
91 | out = self.linear(x)
92 | return out
93 |
94 |
95 |
--------------------------------------------------------------------------------
/scSpace/scspace.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 |
3 | from .models import *
4 | from .utils import *
5 | from natsort import natsorted
6 |
7 |
8 | def construct_pseudo_space(
9 | sc_adata,
10 | st_adata,
11 | kernel_type: str = 'primal',
12 | dim: int = 50,
13 | lamb: int = 1,
14 | gamma: int = 1,
15 | batch_size: int = 16,
16 | hidden_size: int = 128,
17 | common_size: int = 2,
18 | activation: str = 'sigmoid',
19 | lr: float = 0.001,
20 | epoch_num: int = 1000,
21 | log_epoch: int = 100
22 | ):
23 | sc_data = sc_adata.X
24 | st_data = st_adata.X
25 | print('Beginning Transfer Component Analysis...')
26 | tca = TCA(kernel_type=kernel_type, dim=dim, lamb=lamb, gamma=gamma)
27 | sc_new, st_new = tca.fit(Xs=sc_data, Xt=st_data)
28 | print("Transfer Component Analysis done.")
29 | sc_adata.obsm['TCA'] = sc_new
30 | st_adata.obsm['TCA'] = st_new
31 |
32 | st_dataloader = get_data_loader(st_adata=st_adata, batch_size=batch_size)
33 | mlp = init_model(net=sample_MLPEncoder(input_size=dim, common_size=common_size, hidden_size=hidden_size,
34 | activation=activation))
35 | # mlp = init_model(net=MLPEncoder(input_size=dim))
36 | print('Beginning training encoder for source domain...')
37 | losses = []
38 | encoder = train(encoder=mlp, losses=losses, data_loader=st_dataloader,
39 | lr=lr, epoch_num=epoch_num, log_epoch=log_epoch)
40 | print('Encoder for source domain training finished.')
41 |
42 | encoder.eval()
43 | sc_tca = np.array(sc_adata.obsm['TCA'])
44 | predict = encoder(make_cuda(torch.tensor(sc_tca).to(torch.float32)))
45 | pseudo_space = predict.cpu().detach().numpy()
46 | sc_adata.obsm['pseudo_space'] = pseudo_space
47 |
48 | return sc_adata, st_adata
49 |
50 |
51 | def spatial_cluster(
52 | sc_adata,
53 | use_neighbors: bool = True,
54 | l: float = 10,
55 | Ks: int = 10,
56 | Kg: int = 20,
57 | n_comps: int = 50,
58 | alpha: int = 0,
59 | beta: int = 0,
60 | res: float = 0.5,
61 | target_num: Optional[int] = None,
62 | step: float = 0.1,
63 | max_run: int = 20,
64 | random_seed: int = 123,
65 | use_weights: bool = True,
66 | partition_type: Optional[Type[MutableVertexPartition]] = None,
67 | n_iterations: int = -1
68 | ):
69 |
70 | # create space graph
71 | _, knn_idx = knn(data=sc_adata.obsm['pseudo_space'], query=sc_adata.obsm['pseudo_space'], k=Ks+1)
72 | knn_idx = np.delete(knn_idx, 0, axis=1)
73 | N = knn_idx.shape[0]
74 | W = np.diag([1] * N)
75 | for i in range(N):
76 | W[i, knn_idx[i]] = 1
77 |
78 | # create gene expression graph
79 | sc_adata_raw = sc_adata.raw.to_adata()
80 | sc_adata_raw = sc_adata_raw[:, sc_adata_raw.var.highly_variable]
81 | # sc.tl.pca(sc_adata_raw, svd_solver='arpack')
82 | sc.tl.pca(sc_adata_raw, svd_solver='arpack', n_comps=n_comps)
83 | sc_adata.obsm['X_pca'] = sc_adata_raw.obsm['X_pca']
84 |
85 | _, knn_idx_2 = knn(data=sc_adata.obsm['X_pca'], query=sc_adata.obsm['X_pca'], k=Kg+1)
86 | knn_idx_2 = np.delete(knn_idx_2, 0, axis=1)
87 |
88 | if use_neighbors:
89 | print('Calculating spatial weights using the neighbours of spots...')
90 | # create spatial-weighted gene expression graph
91 | sp_weight = np.zeros((knn_idx_2.shape[0], knn_idx_2.shape[1]))
92 | sp_graph = ig.Graph.Adjacency((W > 0).tolist())
93 | sp_graph = ig.Graph.simplify(sp_graph)
94 | for i in range(knn_idx_2.shape[0]):
95 | to_idx = knn_idx_2[i, ]
96 | sp_weight[i, ] = sp_graph.shortest_paths(i, to_idx, mode='all')[0]
97 |
98 | sp_weight = 1 / (alpha + sp_weight) + beta
99 | adjacency = np.zeros((sp_weight.shape[0], sp_weight.shape[0]))
100 | for i in range(N):
101 | adjacency[i, knn_idx_2[i]] = sp_weight[i]
102 | else:
103 | print('Calculating spatial weights using the distances across spots...')
104 | pairwise_dist = euclid_dist(coord=sc_adata.obsm['pseudo_space'])
105 | sp_weight = np.exp(-1 * (pairwise_dist**2) / (2 * (l**2)))
106 | adjacency = np.zeros((knn_idx_2.shape[0], knn_idx_2.shape[0]))
107 | for i in range(knn_idx_2.shape[0]):
108 | to_idx = knn_idx_2[i, ]
109 | adjacency[i, knn_idx_2[i]] = sp_weight[i][to_idx]
110 |
111 | g = get_igraph_from_adjacency(adjacency=adjacency, directed=None)
112 |
113 | if target_num is None:
114 | print('Unsupervised clustering with res = ', res, '...')
115 | cluster = run_leiden(g=g, resolution=res, random_state=random_seed, use_weights=use_weights,
116 | n_iterations=n_iterations, partition_type=partition_type)
117 | else:
118 | assert target_num > 1, 'Target cluster number must be greater than 1!'
119 | recommended_res = search_res(g=g, target_num=target_num, start=res, step=step,
120 | random_state=random_seed, max_run=max_run)
121 | cluster = run_leiden(g=g, resolution=recommended_res, random_state=random_seed, use_weights=use_weights,
122 | n_iterations=n_iterations, partition_type=partition_type)
123 |
124 | sc_adata.obs['scSpace'] = pd.Categorical(
125 | values=cluster.astype('U'),
126 | categories=natsorted(map(str, np.unique(cluster))),
127 | )
128 |
129 | return sc_adata
130 |
131 |
132 | # def spatial_cluster_sub(
133 | # sc_adata,
134 | # celltype_key: str,
135 | # select_cell_type: list,
136 | # Ks: int = 10,
137 | # Kg: int = 20,
138 | # alpha: int = 0,
139 | # beta: int = 0,
140 | # res: float = 0.5,
141 | # target_num: Optional[int] = None,
142 | # step: float = 0.1,
143 | # random_seed: int = 123,
144 | # use_weights: bool = True,
145 | # partition_type: Optional[Type[MutableVertexPartition]] = None,
146 | # n_iterations: int = -1
147 | # ):
148 | # sc_adata_sub = sc_adata[sc_adata.obs[celltype_key].isin(select_cell_type)]
149 | # sc_adata_sub = spatial_cluster(sc_adata=sc_adata_sub, Ks=Ks, Kg=Kg, alpha=alpha, beta=beta, res=res,
150 | # target_num=target_num, step=step, random_seed=random_seed, use_weights=use_weights,
151 | # partition_type=partition_type, n_iterations=n_iterations)
152 | #
153 | # sc_adata.obs['scSpace'] = sc_adata.obs[celltype_key]
154 | # sc_adata.obs.loc[sc_adata_sub.obs.index, 'scSpace'] = sc_adata_sub.obs['scSpace']
155 | #
156 | # return sc_adata
157 |
158 |
159 |
--------------------------------------------------------------------------------
/scSpace/utils.py:
--------------------------------------------------------------------------------
1 | import math
2 | from typing import Optional, Tuple, Sequence, Type
3 | import numpy as np
4 | import scanpy as sc
5 | import anndata as ad
6 | import pandas as pd
7 | from torch.utils.data import Dataset, DataLoader
8 | from torch import nn
9 | import torch
10 | import torch.backends.cudnn as cudnn
11 | import torch.optim as optim
12 | from sklearn.neighbors import KDTree
13 | from sklearn.neighbors import NearestNeighbors
14 | from tqdm import tqdm
15 | import igraph as ig
16 | import leidenalg
17 | import logging as logg
18 |
19 | try:
20 | from leidenalg.VertexPartition import MutableVertexPartition
21 | except ImportError:
22 |
23 | class MutableVertexPartition:
24 | pass
25 |
26 |
27 | MutableVertexPartition.__module__ = 'leidenalg.VertexPartition'
28 |
29 |
30 | class MyDataset(Dataset): # 需要继承data.Dataset
31 | def __init__(self, data, label):
32 | # 1. Initialize file path or list of file names.
33 | self.data = data
34 | self.label = label
35 |
36 | def __getitem__(self, idx):
37 | # TODO
38 | tmp_x = self.data[idx]
39 | tmp_y_tag = self.label[idx]
40 |
41 | return (tmp_x, tmp_y_tag) # tag 分类
42 |
43 | def __len__(self):
44 | # You should change 0 to the total size of your dataset.
45 | return self.label.shape[0]
46 |
47 |
48 | def load_data(
49 | sc_data_path: str,
50 | sc_meta_path: str,
51 | st_data_path: str,
52 | st_meta_path: str,
53 | spatial_key: list = ['xcoord', 'ycoord']
54 | ):
55 | """
56 | load scRNA-seq data and spatial transcriptomic data, and return to AnnData objects
57 | :param sc_data_path: input scRNA-seq data file path
58 | :param sc_meta_path: input scRNA-seq meta file path
59 | :param st_data_path: input spatial transcriptomic data file path
60 | :param st_meta_path: input spatial transcriptomic data file path
61 | :param spatial_key: the columns of spatial coordinates
62 | :return: AnnData objects of scRNA-seq data and spatial transcriptomic data
63 | """
64 |
65 | print('Loading data...')
66 | sc_meta = pd.read_csv(sc_meta_path, index_col=0)
67 | sc_data = pd.read_csv(sc_data_path, index_col=0)
68 | st_meta = pd.read_csv(st_meta_path, index_col=0)
69 | st_data = pd.read_csv(st_data_path, index_col=0)
70 | print('Data have been loaded.')
71 |
72 | sc_adata = ad.AnnData(sc_data.T)
73 | sc_adata.obs = sc_meta
74 |
75 | st_adata = ad.AnnData(st_data.T)
76 | st_adata.obs = st_meta
77 | st_adata.obsm['spatial'] = np.array(st_meta[spatial_key])
78 |
79 | return sc_adata, st_adata
80 |
81 |
82 | # sc_obj, st_obj = load_data(sc_data_path='/home/qjy321/workspace/scspace_dev/scSpace/data/demo_sc_data.csv',
83 | # sc_meta_path='/home/qjy321/workspace/scspace_dev/scSpace/data/demo_sc_meta.csv',
84 | # st_data_path='/home/qjy321/workspace/scspace_dev/scSpace/data/demo_st_data.csv',
85 | # st_meta_path='/home/qjy321/workspace/scspace_dev/scSpace/data/demo_st_meta.csv')
86 |
87 |
88 | def preporcess(
89 | sc_adata,
90 | st_adata,
91 | st_type: str = 'spot',
92 | n_features: int = 2000,
93 | normalize: bool = True,
94 | select_hvg: str = 'intersection'
95 | ):
96 | """
97 | pre-process the scRNA-seq and spatial transcriptomics data (find HVGs and normalized the data)
98 | :param select_hvg: 'intersection' or 'union'
99 | :param sc_adata: AnnData object of scRNA-seq data
100 | :param st_adata: AnnData object of spatial transcriptomics data
101 | :param st_type: the type of spatial transcriptomics data, `spot` or `image`
102 | :param n_features: the number of HVGs to select
103 | :param normalize: whether to normalize the data or not
104 | :return: AnnData object of processed scRNA-seq data and spatial transcriptomic data
105 | """
106 |
107 | assert sc_adata.shape[1] >= n_features, 'There are too few genes in scRNA-seq data, please check again!'
108 | sc.pp.highly_variable_genes(sc_adata, flavor="seurat_v3", n_top_genes=n_features)
109 |
110 | assert st_type in ['spot',
111 | 'image'], 'Please select the correct type of spatial transcriptomic data, `spot` or `image`!'
112 |
113 | if st_type == 'spot':
114 | assert st_adata.shape[1] >= n_features, 'There are too few genes in ST data, please check again!'
115 | sc.pp.highly_variable_genes(st_adata, flavor="seurat_v3", n_top_genes=n_features)
116 | elif st_type == 'image':
117 | if st_adata.shape[1] >= n_features:
118 | sc.pp.highly_variable_genes(st_adata, flavor="seurat_v3", n_top_genes=n_features)
119 | else:
120 | sc.pp.highly_variable_genes(st_adata, flavor="seurat_v3", n_top_genes=st_adata.shape[1])
121 |
122 | if normalize:
123 | # sc_adata
124 | sc.pp.normalize_total(sc_adata, target_sum=1e4)
125 | sc.pp.log1p(sc_adata)
126 | # st_adata
127 | sc.pp.normalize_total(st_adata, target_sum=1e4)
128 | sc.pp.log1p(st_adata)
129 |
130 | sc_adata.raw = sc_adata
131 | st_adata.raw = st_adata
132 |
133 | sc_hvg = sc_adata.var['highly_variable'][sc_adata.var['highly_variable'] == True].index
134 | st_hvg = st_adata.var['highly_variable'][st_adata.var['highly_variable'] == True].index
135 | if select_hvg == 'intersection':
136 | inter_gene = set(sc_hvg).intersection(set(st_hvg))
137 | elif select_hvg == 'union':
138 | sc_gene = set(sc_adata.var_names)
139 | st_gene = set(st_adata.var_names)
140 | common_gene = set(sc_gene).intersection(set(st_gene))
141 |
142 | inter_gene = set(sc_hvg).union(set(st_hvg))
143 | inter_gene = set(inter_gene).intersection(set(common_gene))
144 |
145 | sc_adata = sc_adata[:, list(inter_gene)]
146 | st_adata = st_adata[:, list(inter_gene)]
147 |
148 | print('Data have been pre-processed.')
149 |
150 | return sc_adata, st_adata
151 |
152 |
153 | # sc_obj, st_obj = preporcess(sc_adata=sc_obj, st_adata=st_obj, st_type='image', n_features=2000, normalize=True)
154 |
155 |
156 | def init_model(net):
157 | """Init models with cuda."""
158 |
159 | # check if cuda is available
160 | if torch.cuda.is_available():
161 | cudnn.benchmark = True
162 | net.cuda()
163 |
164 | return net
165 |
166 |
167 | def make_cuda(tensor):
168 | """Use CUDA if it's available."""
169 | if torch.cuda.is_available():
170 | tensor = tensor.cuda()
171 | return tensor
172 |
173 |
174 | def get_data_loader(
175 | st_adata,
176 | batch_size: int = 16,
177 | ):
178 | """Get dataset loader."""
179 | # dataset
180 | data = torch.tensor(np.array(st_adata.obsm['TCA'])).to(torch.float32)
181 | label = torch.tensor(np.array(st_adata.obsm['spatial'])).to(torch.float32)
182 |
183 | # data loader
184 | dataloader = DataLoader(
185 | dataset=MyDataset(data=data, label=label),
186 | batch_size=batch_size,
187 | shuffle=True)
188 |
189 | return dataloader
190 |
191 |
192 | def train(
193 | encoder,
194 | data_loader,
195 | losses,
196 | lr: float = 0.001,
197 | epoch_num: int = 1000,
198 | log_epoch: int = 100
199 | ):
200 | """Train source domain."""
201 | ####################
202 | # 1. setup network #
203 | ####################
204 |
205 | # set train state for Dropout and BN layers
206 | encoder.train()
207 |
208 | # setup criterion and optimizer
209 | optimizer = optim.Adam(encoder.parameters(), lr=lr)
210 | criterion = nn.MSELoss(reduction='mean')
211 |
212 | ####################
213 | # 2. train network #
214 | ####################
215 |
216 | for epoch in tqdm(range(epoch_num)):
217 | batch_loss = []
218 | for step, data in enumerate(data_loader):
219 | features, labels = data
220 |
221 | features = make_cuda(features)
222 | labels = make_cuda(labels)
223 |
224 | # zero gradients for optimizer
225 | optimizer.zero_grad()
226 |
227 | # compute loss for critic
228 | pred = encoder(features)
229 | loss = criterion(pred, labels)
230 |
231 | # optimize source classifier
232 | loss.backward()
233 | optimizer.step()
234 |
235 | batch_loss.append(loss.cpu().data.numpy())
236 |
237 | # print
238 | if (epoch + 1) % log_epoch == 0:
239 | losses.append(np.mean(batch_loss))
240 | print("Epoch [{}/{}]: Batch loss={}"
241 | .format(epoch + 1,
242 | epoch_num,
243 | np.mean(batch_loss)))
244 |
245 | return encoder
246 |
247 |
248 | def knn(data, query, k):
249 | tree = KDTree(data)
250 | dist, ind = tree.query(query, k)
251 | return dist, ind
252 |
253 |
254 | def euclid_dist(coord):
255 | """
256 | Calculate Euclidean distance between points
257 | """
258 | dis = []
259 | for i in range(len(coord)):
260 | dis.append([])
261 | for j in range(len(coord)):
262 | dis[i].append(math.dist(coord[i], coord[j]))
263 | dis = np.array(dis)
264 | return dis
265 |
266 |
267 | def get_igraph_from_adjacency(adjacency, directed=None):
268 | """Get igraph graph from adjacency matrix."""
269 |
270 | sources, targets = adjacency.nonzero()
271 | weights = adjacency[sources, targets]
272 | if isinstance(weights, np.matrix):
273 | weights = weights.A1
274 | g = ig.Graph(directed=directed)
275 | g.add_vertices(adjacency.shape[0]) # this adds adjacency.shape[0] vertices
276 | g.add_edges(list(zip(sources, targets)))
277 | try:
278 | g.es['weight'] = weights
279 | except KeyError:
280 | pass
281 | if g.vcount() != adjacency.shape[0]:
282 | logg.warning(
283 | f'The constructed graph has only {g.vcount()} nodes. '
284 | 'Your adjacency matrix contained redundant nodes.'
285 | )
286 | return g
287 |
288 |
289 | def run_leiden(
290 | g,
291 | resolution: float = 0.5,
292 | random_state: int = 123,
293 | use_weights: bool = True,
294 | n_iterations: int = -1,
295 | partition_type: Optional[Type[MutableVertexPartition]] = None,
296 | ):
297 | """
298 | run Leiden clustering algorithm
299 | :param g: spatial-weighted gene expression graph
300 | :param resolution: A parameter value controlling the coarseness of the clustering.
301 | Higher values lead to more clusters.
302 | :param random_state: Change the initialization of the optimization.
303 | :param use_weights: If `True`, edge weights from the graph are used in the computation
304 | :param n_iterations: How many iterations of the Leiden clustering algorithm to perform.
305 | Positive values above 2 define the total number of iterations to perform,
306 | -1 has the algorithm run until it reaches its optimal clustering.
307 | :param partition_type: Type of partition to use. Defaults to :class:`~leidenalg.RBConfigurationVertexPartition`.
308 | For the available options, consult the documentation for :func:`~leidenalg.find_partition`.
309 | :return: clustering results
310 | """
311 |
312 | partition_kwargs = dict()
313 |
314 | if partition_type is None:
315 | partition_type = leidenalg.RBConfigurationVertexPartition
316 | if use_weights:
317 | partition_kwargs['weights'] = np.array(g.es['weight']).astype(np.float64)
318 | partition_kwargs['n_iterations'] = n_iterations
319 | partition_kwargs['seed'] = random_state
320 | if resolution is not None:
321 | partition_kwargs['resolution_parameter'] = resolution
322 | # clustering proper
323 | part = leidenalg.find_partition(g, partition_type, **partition_kwargs)
324 | groups = np.array(part.membership)
325 |
326 | return groups
327 |
328 |
329 | def search_res(
330 | g,
331 | target_num,
332 | start: float = 0.5,
333 | step: float = 0.1,
334 | random_state: int = 123,
335 | max_run: int = 10,
336 |
337 | ):
338 | res = start
339 | print("Start at res = ", res, "step = ", step)
340 | original_group = run_leiden(g=g, resolution=res, random_state=random_state)
341 | original_num = len(np.unique(original_group))
342 | print("Res = ", res, "number of clusters = ", original_num)
343 | run = 0
344 |
345 | while original_num != target_num:
346 | sign = 1 if (original_num < target_num) else -1
347 | new_group = run_leiden(g=g, resolution=(res + step * sign), random_state=random_state)
348 | new_num = len(np.unique(new_group))
349 | print("Res = ", (res + step * sign), "number of clusters = ", new_num)
350 |
351 | if new_num == target_num:
352 | res = res + step * sign
353 | print("Recommended res = ", res)
354 | return res
355 |
356 | new_sign = 1 if (new_num < target_num) else -1
357 | if new_sign == sign:
358 | res = res + step * sign
359 | print("Res changed to", res)
360 | original_num = new_num
361 | else:
362 | step = step / 2
363 | print("Step changed to", step)
364 |
365 | assert res > 0, 'Res must be positive! Please increase the number of target clusters!'
366 |
367 | if run > max_run:
368 | print('No resolution found, recommended res = ', res)
369 | return res
370 | run += 1
371 |
372 | print("Recommended res = ", res)
373 |
374 | return res
375 |
376 |
377 | # TODO: Add comments
378 | def cal_dist(coord,
379 | normalize: bool = True):
380 | dist = []
381 | for i in tqdm(range(len(coord))):
382 | xi, yi = coord[i, :]
383 | for j in range(len(coord)):
384 | if i >= j:
385 | continue
386 | xj, yj = coord[j, :]
387 | dist_tmp = np.sqrt((xi - xj) ** 2 + (yi - yj) ** 2)
388 | dist.append(dist_tmp)
389 |
390 | if normalize:
391 | dist = dist / max(dist)
392 |
393 | return dist
394 |
395 |
396 | def cal_dist_group(sc_adata, group_key, select_group):
397 | coord_all = sc_adata.obsm['pseudo_space']
398 |
399 | group_df = sc_adata.obs[group_key]
400 | group_df = group_df.reset_index()
401 | group = list(np.unique(group_df[group_key]))
402 | assert select_group in group, 'Please select the correct group!'
403 |
404 | select_idx = group_df[group_df[group_key] == select_group].index
405 | selsct_coord = coord_all[select_idx]
406 |
407 | # dist_all = pd.DataFrame(columns=['dist', 'group'])
408 | dist_all = []
409 | for g in group:
410 | print('Calculating all cell pairs between', select_group, 'and', g, '...')
411 | dist_group = []
412 | tmp_idx = group_df[group_df[group_key] == g].index
413 | tmp_coord = coord_all[tmp_idx]
414 |
415 | if g == select_group:
416 | for i in tqdm(range(len(tmp_coord))):
417 | xi, yi = tmp_coord[i, :]
418 | for j in range(len(selsct_coord)):
419 | if i >= j:
420 | continue
421 | xj, yj = selsct_coord[j, :]
422 | dist_tmp = np.sqrt((xi - xj) ** 2 + (yi - yj) ** 2)
423 | dist_group.append(dist_tmp)
424 | else:
425 | for i in tqdm(range(len(tmp_coord))):
426 | xi, yi = tmp_coord[i, :]
427 | for j in range(len(selsct_coord)):
428 | xj, yj = selsct_coord[j, :]
429 | dist_tmp = np.sqrt((xi - xj) ** 2 + (yi - yj) ** 2)
430 | dist_group.append(dist_tmp)
431 |
432 | dist_all.append(dist_group)
433 |
434 | return dist_all
435 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | from setuptools import setup
2 |
3 |
4 | setup(
5 | name="scSpace",
6 | version="1.0.0",
7 | description='Reconstruction of cell pseudo space from single-cell RNA sequencing data',
8 | author='Jingyang Qian',
9 | author_email='qianjingyang@zju.edu.cn',
10 | url='https://github.com/ZJUFanLab/scSpace',
11 | packages=['scSpace'],
12 | install_requires=[],
13 | python_requires='>=3.8',
14 | license='GNU General Public License v3.0',
15 | )
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------