美文网首页单细胞转录组单细胞测序单细胞
基于Seurat UAMP和celltype的RNA Veloc

基于Seurat UAMP和celltype的RNA Veloc

作者: Yu_Lin | 来源:发表于2022-04-24 22:37 被阅读0次

    参考资料:
    参考生物技能树
    Velocyto官网Tutorial
    scvelo实战教程
    Seurat-to-RNA-Velocity
    分析步骤:
    本教程是velocyto基于Seurat对象中UMAP和细胞类型进行RNA速率分析,推断细胞Cluster命运的状态(过渡与稳定)和分化方向性(轨迹)。
    第一步:在linux系统中用velocyto将bam文件转换成loom文件;
    第二步:按照scvelo需要的格式获取seurat中的UMAP坐标和Celltype信息;
    第三步:在 python程序中整合loom文件和UMAP坐标和Celltype数据,并进行下游速率分析。

    1、将bam文件转换成loom文件(Linux系统操作)

    1.1 conda安装velocyto的一些依赖

    需要一些依赖

    conda create -n velocyto 
    conda activate velocyto 
    conda install samtools
    conda install numpy scipy cython numba matplotlib scikit-learn h5py click
    pip install pysam
    pip install velocyto
    

    Successfully installed loompy-3.0.6 numpy-groupies-0.9.13 pandas-1.2.5 pytz-2021.1 velocyto-0.17.17

    1.2 下载特定物种的特殊gtf文件(这个步骤是可选的)

    你如果要屏蔽repetetive elements,可以使用这一步骤
    我们这个单细胞转录组使用cellranger流程的话,需要重复数据的gtf文件,rmsk。
    进入UCSC官网,在Tools菜单中打开Table Brower,选择目的物种以及个性化的需求

    1650200197137.jpg
    1.3 bam文件循环进行sort

    理论上,这下一步命令,就可以完成bam转换成loom文件,但是因为 samtools问题,上面的流程可能是会失败。这个时候可以自行先运行 samtools sort 命令处理得到 cellsorted_possorted_genome_bam.bam 文件。

     ls  */outs/possorted_genome_bam.bam|while read id
    do  new=${id/possorted_genome_bam.bam/cellsorted_possorted_genome_bam.bam}
    echo $new 
    samtools sort -@ 4  -t CB -O BAM -o $new   $id  
     done
    
    1.4 bam文件循环运行velocyto
    #! /bin/sh
    rmsk_gtf=/lustre/home/acct-medxh/medxh/sccdata/Rawdata/reference/hg38_repeat_rmsk.gtf # 从genome.ucsc.edu下载 
    cellranger_outDir=/lustre/home/acct-medxh/medxh/sccdata/Rawdata/output_EC3 # 这个输出目录可以随便选择文件夹,但是最后一个文件夹决定了loom的细胞名字如”output_EU1:TTTCCTCAGTCCGCGTx“,所以output_EU1尽量为样品名
    cellranger_gtf=/lustre/home/acct-medxh/medxh/yard/reference/refdata-gex-GRCh38-2020-A/genes/genes.gtf # 这个是cellranger官网提供的
    ls -lh $rmsk_gtf  $cellranger_outDir $cellranger_gtf
    ls -d *-*|while read cellranger_outDir
    do 
    velocyto run10x -m $rmsk_gtf  $cellranger_outDir $cellranger_gtf 
    done
    

    2、Seurat UMAP和Celltype提取(R和python)

    参考官网https://scvelo.readthedocs.io/getting_started/

    2.1 提取seurat中的cells、UMAP、celltype (R studio)
    setwd("~/Desktop/bioinformation/End_analysis/velocyto")
    library(dplyr)
    library(ggplot2)
    library(cowplot)
    library(patchwork)
    suppressMessages(library(Seurat))
    End.combined <- readRDS("~/Desktop/bioinformation/End_analysis/End.combined.rds")
    
    2.2 提取对象
    table(End.combined$group)
    Idents(object=End.combined)<-End.combined$group
    Eutopic<-subset(End.combined, idents = c("Eutopic"), invert = F)
    
    2.3 修改Cells名字(”ATCCCTGTCACTGAAC-1_1")保持和loom中cell ID("output_EU3:TTTGACTGTTGCCGACx")一致
    df<-data.frame(Cells=Cells(Eutopic),sample=paste("output_EU",Eutopic$sampleID,sep = ""))#制做data.frame,含有cells和output_EU3
    df$id<-sapply(df$Cells,function(x)paste(unlist(strsplit(x, "-"))[1],"x",sep = ""))#将“-”之前的字符和“x”连接
    df$Cells<-paste(df$sample,df$id,sep = ":")#将“output_EU3”和Cells通过“:”连接
    write.csv(df$Cells, file = "cellID_obs.csv", row.names = FALSE) #提取修改后的cell ID
    
    cell_embeddings<-Embeddings(Eutopic, reduction = "umap")#使用Embeddings功能提取seurat UMAP或者TSNE
    rownames(cell_embeddings)<-df$Cells #修改rowname的名字使其和cell ID一致
    write.csv(cell_embeddings, file = "cell_embeddings.csv")
    clusters_obs<-Eutopic$celltype.1 #提取celltype
    names(clusters_obs)<-df$Cells #修改名字和保持cell ID一致
    write.csv(clusters_obs, file = "clusters_obs.csv")
    

    3、anndata导入loom文件和Seurat中meta-data并进行下游速率分析(多样本整合)

    3.1加载依赖包
    cona activate velocyto
    python
    import anndata
    import scvelo as scv
    import pandas as pd
    import numpy as np
    import matplotlib as plt
    
    3.2 读取每个样品中的loom文件
    sample_one = anndata.read_loom("/Users/linyu1/Desktop/bioinformation/End_analysis/velocyto/output_EU1.loom")
    ##Variable names are not unique. To make them unique, call `.var_names_make_unique`.
    sample_one.var_names_make_unique()
    sample_one
    ##AnnData object with n_obs × n_vars = 5992 × 36601
    #    obs: 'Clusters', '_X', '_Y'
    #   var: 'Accession', 'Chromosome', 'End', 'Start', 'Strand'
    #    layers: 'matrix', 'ambiguous', 'spliced', 'unspliced'
    sample_two = anndata.read_loom("/Users/linyu1/Desktop/bioinformation/End_analysis/velocyto/output_EU2.loom")
    sample_two.var_names_make_unique()
    sample_three = anndata.read_loom("/Users/linyu1/Desktop/bioinformation/End_analysis/velocyto/output_EU3.loom")
    sample_three.var_names_make_unique()
    
    3.3 读取seurat中cells、UMAP和celltype的信息
    sample_obs = pd.read_csv("/Users/linyu1/Desktop/bioinformation/End_analysis/velocyto/cellID_obs.csv")
    umap = pd.read_csv("/Users/linyu1/Desktop/bioinformation/End_analysis/velocyto/cell_embeddings.csv")
    cell_clusters = pd.read_csv("/Users/linyu1/Desktop/bioinformation/End_analysis/velocyto/clusters_obs.csv")
    
    3.4 在每个样品loom中过滤出seurat中选择的Cell ID
    sample_one = sample_one[np.isin(sample_one.obs.index,sample_obs["x"])]
    sample_two = sample_two[np.isin(sample_two.obs.index,sample_obs["x"])]
    sample_three = sample_three[np.isin(sample_three.obs.index,sample_obs["x"])]
    
    3.5 将过滤后的文件整合成一个文件
    adata = sample_one.concatenate(sample_two, sample_three)
    
    3.6 将umap坐标和celltype添加到anndata 对象中

    需要确保我们添加umapCell ID和anndata对象中的Cell ID的顺序完全匹配,Cell ID是对象的观察层中的行名,因此我们可以使用以下方法更改
    一步、我们把index提取成表达矩阵并更改列名;
    二步、由于多个样品合并成adata时Cell ID后面多了“-0”(如下图),为了完全匹配Cell ID,通过apply和split去除“-0”(保证adata和seurat中barcode名字相同);
    三步、umap坐标和celltype添加到anndata 对象。

    adata_index = pd.DataFrame(adata.obs.index)
    adata_index = adata_index.rename(columns = {0:'Cell ID'})
    adata_index = adata_index.rename(columns = {"CellID":'Cell ID'})
    
    rep=lambda x : x.split("-")[0]
    adata_index["Cell ID"]=adata_index["Cell ID"].apply(rep)
    
    umap = umap.rename(columns = {'Unnamed: 0':'Cell ID'})#更改umap的列名统一相同的列名Cell ID
    umap = umap[np.isin(umap["Cell ID"],adata_index["Cell ID"])] #过滤adata_index在umap中的cell ID
    umap=umap.drop_duplicates(subset=["Cell ID"]) #去除重复值
    umap_ordered = adata_index.merge(umap, on = "Cell ID")#依据adata_index Cell ID顺序与umap的数据进行合并
    umap_ordered = umap_ordered.iloc[:,1:] #去除umap_ordered中的第一列
    adata.obsm['X_umap'] = umap_ordered.values #将UMAP并入到adata对象中
    
    
    cell_clusters=cell_clusters.iloc[:,1:]
    cell_clusters = cell_clusters.rename(columns = {'cell':'Cell ID'})
    cell_clusters = cell_clusters[np.isin(cell_clusters["Cell ID"],adata_index["Cell ID"])]
    cell_clusters=cell_clusters.drop_duplicates(subset=["Cell ID"]) #去除重复值
    cell_clusters_ordered = adata_index.merge(cell_clusters, on = "Cell ID")
    cell_clusters_ordered = cell_clusters_ordered.iloc[:,1:]
    adata.obs['clusters']=cell_clusters_ordered.values
    
    3.8 运行RNA Velocity

    我们现在可以运行scVelo命令,并根据Seurat UMAP坐标生成RNA速度图

    scv.pp.filter_and_normalize(adata)
    scv.pp.moments(adata)
    scv.tl.velocity(adata, mode = "stochastic")
    scv.tl.velocity_graph(adata)
    
    3.9 spliced/unspliced的比例
    scv.pl.proportions(adata)
    
    splice.png
    3.10 可视化
    scv.pl.velocity_embedding(adata, basis = 'umap')
    
    2.png
    scv.pl.velocity_embedding_stream(adata, basis = 'umap')
    
    3.png
    3.11 解释velocities

    这可能是最重要的部分,因为我们建议用户不要将生物学结论局限于预测的速度,而是通过阶段画像来检查个体基因动力学,以了解推断的方向是如何由特定基因支持的。

    参考下图思考如何解释spliced vs. unspliced 时相特征[图1.6a]。基因活性是由转录调控调控的。对特定基因的转录的诱导表达,会导致前体unspliced mRNAs 的增加,而相反地,转录抑制或缺失会导致unspliced mRNAs 的减少。spliced mRNA由未剪接的unspliced的mRNA产生,具有相同的趋势,但存在时间滞后。时间是一个隐藏/潜在的变量。因此,动力学需要从实际测量的东西来推断: 在相位图中显示的剪接和未剪接的mrna。


    图1.6a

    用scv.pl.velocity(adata, gene_names检查某些特定基因的时相特征

    scv.pl.velocity(adata, ['Cpe',  'Gnao1', 'Ins2', 'Adk'], ncols=2)
    
    图1.6b

    黑线对应于估计的“稳态”比率,即处于恒定转录状态的spliced 和 unspliced mRNA丰度之比。一个特定基因的RNA速度是由残差决定的,即观察值偏离稳态线的程度。正速度表明一个基因被上调,这种现象发生在细胞中,在稳定状态下,该基因的unspliced mRNA的丰度高于预期。相反,负速度表明基因被下调。

    例如,Cpe解释了上调的Ngn3(黄色)向Pre-endocrine(橙色)向β-cells(绿色)的方向,而Adk解释了下调的Ductal(深绿色)向Ngn3(黄色)向其余内分泌细胞的方向。

    scv.pl.scatter(adata, 'Cpe', color=['clusters', 'velocity'],
                   add_outline='Ngn3 high EP, Pre-endocrine, Beta')
    
    3.12 鉴定重要基因

    我们需要一个系统的方法来识别基因,这可能有助于解释最终的向量场和推断的谱系。为了做到这一点,我们可以测试哪些基因具有集群特有的差异速度表达,与其他种群相比显著地更高或更低。模块scv.tl.rank_velocity_genes运行一个差分速度t检验,并为每个集群输出一个基因排名。可以设置阈值(例如min_corr)来限制对候选基因的测试。

    scv.tl.rank_velocity_genes(adata, groupby='clusters', min_corr=.3)
    
    df = scv.DataFrame(adata.uns['rank_velocity_genes']['names'])
    df.head()
    
    kwargs = dict(frameon=False, size=10, linewidth=1.5,
                  add_outline='Ngn3 high EP, Pre-endocrine, Beta')
    
    scv.pl.scatter(adata, df['Ngn3 high EP'][:5], ylabel='Ngn3 high EP', **kwargs)
    scv.pl.scatter(adata, df['Pre-endocrine'][:5], ylabel='Pre-endocrine', **kwargs)
    

    例如,基因Ptprs、Pclo、Pam、Abcc8、Gnas支持从Ngn3高EP(黄色)到Pre-endocrine(橙色)再到Beta(绿色)的方向性。

    3.13 细胞周期的Velocities分析

    由RNA速度检测的细胞周期,在生物学上由细胞周期分数(阶段标志基因平均表达水平的标准化分数) 确定。

    scv.tl.score_genes_cell_cycle(adata)
    scv.pl.scatter(adata, color_gradients=['S_score', 'G2M_score'], smooth=True, perc=[5, 95])
    
    s_genes, g2m_genes = scv.utils.get_phase_marker_genes(adata)
    s_genes = scv.get_df(adata[:, s_genes], 'spearmans_score', sort_values=True).index
    g2m_genes = scv.get_df(adata[:, g2m_genes], 'spearmans_score', sort_values=True).index
    
    kwargs = dict(frameon=False, ylabel='cell cycle genes')
    scv.pl.scatter(adata, list(s_genes[:2]) + list(g2m_genes[:3]), **kwargs)
    

    特别是hell和Top2a非常适合解释周期祖先中的向量场。Top2a在G2M阶段达到峰值前不久被赋予了一个高速。在这里,负的速度与紧随其后的下调完全匹配。

    scv.pl.velocity(adata, ['Hells', 'Top2a'], ncols=2, add_outline=True)
    
    3.14 速度和一致性

    两个更有用的stats:-速度或分化率是由速度矢量的长度给出的。-矢量场的一致性(即,速度矢量如何与其邻近速度相关联)提供了一个可信度的度量。

    scv.tl.velocity_confidence(adata)
    keys = 'velocity_length', 'velocity_confidence'
    scv.pl.scatter(adata, c=keys, cmap='coolwarm', perc=[5, 95])
    

    这些提供了细胞在哪里以较慢/较快的速度分化
    在集群水平上,我们发现分化在细胞周期退出(Ngn3 low EP)后显著加快,在Beta细胞生产期间保持速度,而在Alpha细胞生产期间减慢速度。

    df = adata.obs.groupby('clusters')[keys].mean().T
    df.style.background_gradient(cmap='coolwarm', axis=1)
    

    3.15 动力学模型

    它在一个基于可能性的期望最大化框架中解决,通过迭代估计反应速率和潜在细胞特异性变量的参数,即转录状态和细胞内部潜伏时间。因此,它的目的是了解每个基因未拼接/已拼接阶段的轨迹。

    scv.tl.recover_dynamics(adata)
    scv.tl.velocity(adata, mode='dynamical')
    scv.tl.velocity_graph(adata)
    #adata.write('data/pancreas.h5ad', compression='gzip')
    #adata = scv.read('data/pancreas.h5ad')
    scv.pl.velocity_embedding_stream(adata, basis='umap')
    
    3.16 动率参数

    在不需要任何实验数据的情况下,可以估计RNA转录、剪接和降解的速率。
    它们有助于更好地理解细胞的特性和表型异质性。

    df = adata.var
    df = df[(df['fit_likelihood'] > .1) & df['velocity_genes'] == True]
    
    kwargs = dict(xscale='log', fontsize=16)
    with scv.GridSpec(ncols=3) as pl:
        pl.hist(df['fit_alpha'], xlabel='transcription rate', **kwargs)
        pl.hist(df['fit_beta'] * df['fit_scaling'], xlabel='splicing rate', xticks=[.1, .4, 1], **kwargs)
        pl.hist(df['fit_gamma'], xlabel='degradation rate', xticks=[.1, .4, 1], **kwargs)
    
    scv.get_df(adata, 'fit*', dropna=True).head()
    

    The estimated gene-specific parameters comprise rates of transription (fit_alpha), splicing (fit_beta), degradation (fit_gamma), switching time point (fit_t_), a scaling parameter to adjust for under-represented unspliced reads (fit_scaling), standard deviation of unspliced and spliced reads (fit_std_u, fit_std_s), the gene likelihood (fit_likelihood), inferred steady-state levels (fit_steady_u, fit_steady_s) with their corresponding p-values (fit_pval_steady_u, fit_pval_steady_s), the overall model variance (fit_variance), and a scaling factor to align the gene-wise latent times to a universal, gene-shared latent time (fit_alignment_scaling).

    3.17 逆时分析

    动态模型恢复了潜在细胞过程的潜在时间。这一潜伏时间代表了细胞的内部时钟,仅根据其转录动力学,与细胞分化时所经历的实时时间近似。

    scv.tl.latent_time(adata)
    scv.pl.scatter(adata, color='latent_time', color_map='gnuplot', size=80)
    
    top_genes = adata.var['fit_likelihood'].sort_values(ascending=False).index[:300]
    scv.pl.heatmap(adata, var_names=top_genes, sortby='latent_time', col_color='clusters', n_convolve=100)
    
    2.3 Top-likelihood基因

    驱动基因表现出明显的动态行为,并通过动态模型中的高可能性对其特征进行系统地检测。

    top_genes = adata.var['fit_likelihood'].sort_values(ascending=False).index
    scv.pl.scatter(adata, basis=top_genes[:15], ncols=5, frameon=False)
    
    var_names = ['Actn4', 'Ppp3ca', 'Cpe', 'Nnat']
    scv.pl.scatter(adata, var_names, frameon=False)
    scv.pl.scatter(adata, x='latent_time', y=var_names, frameon=False)
    
    3.18 Cluster-specific top-likelihood 基因

    此外,可以计算每个细胞集群的部分基因可能性,以实现集群特异性识别潜在驱动因素。

    scv.tl.rank_dynamical_genes(adata, groupby='clusters')
    df = scv.get_df(adata, 'rank_dynamical_genes/names')
    df.head(5)
    
    for cluster in ['Ductal', 'Ngn3 high EP', 'Pre-endocrine', 'Beta']:
        scv.pl.scatter(adata, df[cluster][:5], ylabel=cluster, frameon=False)
    

    相关文章

      网友评论

        本文标题:基于Seurat UAMP和celltype的RNA Veloc

        本文链接:https://www.haomeiwen.com/subject/mywlertx.html