zd200572的个人博客分享 http://blog.sciencenet.cn/u/zd200572

博文

SMURF流程之q2-sidle

已有 3166 次阅读 2021-2-6 16:37 |个人分类:biology|系统分类:科研笔记

前面已经完成了qiime2-sidle插件的安装,测试方法就是输入qiime:

  sidle               Plugin for kmer-based marker gene reconstruction

出现了上面的选项,应该就说明已经安装成功了。

数据库准备

数据库准备是一劳永逸的,前面我们已经完成了数据库过滤的步骤

准备一个区域数据库

这一步是提取一个区域的数据库,基于K-mer,为了提升内存效率,把简并碱基和重复kmer作为一条序列。
在这里插入图片描述

# 首先,使用feature-classifier插件的extract-reads提取,那么对于6V区的SMURF应该是:# 2.2 序列提取# 74f 315R V1-V2qiime feature-classifier extract-reads \
--i-sequences sidle-db-full-degen-filtered-phylum-def-sequences.qza \
--p-f-primer TGGCGGACGGGTGAGTAA \
--p-r-primer CTGCTGCCTCCCGTAGGA \
--o-reads sidle-db-filt-j1.qza # 316F 484R V3部分
qiime feature-classifier extract-reads \
--i-sequences sidle-db-full-degen-filtered-phylum-def-sequences.qza \
--p-f-primer TCCTACGGGAGGCAGCAG \
--p-r-primer  TATTACCGCGGCTGCTGG \
--o-reads sidle-db-filt-j2.qza # 486F 650R V3部分-v4部分
 qiime feature-classifier extract-reads \
--i-sequences sidle-db-full-degen-filtered-phylum-def-sequences.qza \
--p-f-primer CAGCAGCCGCGGTAATAC \
--p-r-primer  CGCATTTCACCGCTACAC \
--o-reads sidle-db-filt-j3.qza # 752F 911 R V5
 qiime feature-classifier extract-reads \
--i-sequences sidle-db-full-degen-filtered-phylum-def-sequences.qza \
--p-f-primer AGGATTAGATACCCTGGT \
--p-r-primer  GAATTAAACCACATGCTC \
--o-reads sidle-db-filt-j4.qza # 901F 1057R V6
 qiime feature-classifier extract-reads \
--i-sequences sidle-db-full-degen-filtered-phylum-def-sequences.qza \
--p-f-primer GCACAAGCGGTGGAGCAT \
--p-r-primer  CGCTCGTTGCGGGACTTA \
--o-reads sidle-db-filt-j5.qza # 1143F 1336R V7 V8
 qiime feature-classifier extract-reads \
--i-sequences sidle-db-full-degen-filtered-phylum-def-sequences.qza \
--p-f-primer AGGAAGGTGGGGATGACG \
--p-r-primer  CCCGGGAACGTATTCACC \
--o-reads sidle-db-filt-j6.qza1234567891011121314151617181920212223242526272829303132333435363738

上sidle插件,文档介绍这里和原方法略有区别,原算法是允许2个碱基不一致,而这里用的80%,作者说可以用–p-identity 参数,但是没找到。。。

 # 可以给region起个别名,看喜好起即可
# P1
qiime sidle prepare-extracted-region \
--i-sequences sidle-db-filt-j1.qza \
--p-region "P1" \
--p-fwd-primer TGGCGGACGGGTGAGTAA \
--p-rev-primer CTGCTGCCTCCCGTAGGA \
--p-trim-length 100 \
--o-collapsed-kmers sidle-db-P1-100nt-kmers.qza \
--o-kmer-map sidle-db-P1-100nt-map.qza
# P2
 qiime sidle prepare-extracted-region \
--i-sequences sidle-db-filt-j2.qza \
--p-region "P2" \
--p-fwd-primer TCCTACGGGAGGCAGCAG \
--p-rev-primer  TATTACCGCGGCTGCTGG \
--p-trim-length 100 \
--o-collapsed-kmers sidle-db-P2-100nt-kmers.qza \
--o-kmer-map sidle-db-P2-100nt-map.qza
# P3
 qiime sidle prepare-extracted-region \
--i-sequences sidle-db-filt-j3.qza \
--p-region "P3" \
--p-fwd-primer CAGCAGCCGCGGTAATAC \
--p-rev-primer  CGCATTTCACCGCTACAC \
--p-trim-length 100 \
--o-collapsed-kmers sidle-db-P3-100nt-kmers.qza \
--o-kmer-map sidle-db-P3-100nt-map.qza
# P4
 qiime sidle prepare-extracted-region \
--i-sequences sidle-db-filt-j4.qza \
--p-region "P4" \
--p-fwd-primer AGGATTAGATACCCTGGT \
--p-rev-primer  GAATTAAACCACATGCTC \
--p-trim-length 100 \
--o-collapsed-kmers sidle-db-P4-100nt-kmers.qza \
--o-kmer-map sidle-db-P4-100nt-map.qza
# P5
 qiime sidle prepare-extracted-region \
--i-sequences sidle-db-filt-j5.qza \
--p-region "P5" \
--p-fwd-primer GCACAAGCGGTGGAGCAT \
--p-rev-primer  CGCTCGTTGCGGGACTTA \
--p-trim-length 100 \
--o-collapsed-kmers sidle-db-P5-100nt-kmers.qza \
--o-kmer-map sidle-db-P5-100nt-map.qza
# P6
 qiime sidle prepare-extracted-region \
--i-sequences sidle-db-filt-j6.qza \
--p-region "P6" \
--p-fwd-primer AGGAAGGTGGGGATGACG \
--p-rev-primer  CCCGGGAACGTATTCACC \
--p-trim-length 100 \
--o-collapsed-kmers sidle-db-P6-100nt-kmers.qza \
--o-kmer-map sidle-db-P6-100nt-map.qza

这步会输出含简并的序列,移除重复序列和一个kmer映射文件,可以qiime可视化,给出原始数据库序列名称(db-seq)、序列名称(seq-name)、区域标识(Kmer)、引物(fwd-primer和rev-primer)、区域(Region)和序列长度(Trim-Length)之间的关系。

# 如果参考序列不能覆盖正反向引物,可以把--p-trim-length设置为负值,增加个参数--p-reverse-complement-result 
--i-sequences sidle-db-filt-jl.qza \
--p-region "Batman" \
--p-fwd-primer TATTACCGCGGCTGCTGG \
--p-rev-primer TCCTACGGGAGGCAGCAG \
--p-trim-length -100 \
--p-reverse-complement-result \
--o-collapsed-kmers sidle-db-batman-100nt-kmers.qza \
--o-kmer-map sidle-db-batman-100nt-map.qza


完成了前面的数据库准备,下面就是reads的准备,基本过程就是把reads拆成对应不同引物的几个部分,后面再重建合并在一起啦。首先声明,这个方法还在开发和完善之路,最近一次更新在这个月,可能结果会有变动,应该说还处于beta版本中,不建议在生产环境中使用。
这里就有几种情况啦,一种是已经每个样本每个V区拆好的数据,另一种是每个样本几个V区混在一起的数据,或者完全没拆的数据。这里根据SMURF的示例,按第二种情况进行,应该是最常见的情况。下面是具体步骤:

Reads准备

尽管SMURF依赖于质控过滤,还是推荐继续使用去噪的方法。推荐使用现有的方法进行预处理,当然可以用别的方法替代,这只是一个例子。
简单来说步骤就是分而治之,最后合并,作者也说了这个方法其实是可以用来meta分析的,但是我还是对meta分析持怀疑态度的,毕竟每个实验室使用的方法区别那么大,样本保存条件不一样,提取方法有区别,再有就是PCR扩增区域、引物和酶也是有区别,还有建库方法的不一致,这样下来,区别差到天涯海角了,meta分析只能得出一个有问题的结论吧!16S/宏基因组,微生物、微生态的研究亟需一个标准化吧,否则每个结果只能对每个实验室的方法负责了,完全失去了可比性。对于这篇文章中使用的引物,我发现多数不是最常用的引物,所以结果是不是有偏差,也是一个值得思考的问题呀! 好,回归正题!

拆数据

我们这里用的是PE150的示例数据,没有进行样本拆分,那么使用多q2-cutadapt的trim-paired切去引物,–p-discard-untrimmed移除没有引物的序列。如果正反向序列不能拼接,当做单独的序列进行处理。

首先,导入数据,导入前重命名一下,以适应导入格式要求,个人觉得这样导入最简单。

# 重命名
mv Example_L001_R1_001.fastq.gz 1_Example_L001_R1_001.fastq.gz
mv Example_L001_R2_001.fastq.gz 1_Example_L001_R2_001.fastq.gz
# 导入
qiime tools import \
 --type 'SampleData[PairedEndSequencesWithQuality]' \
 --input-path . \
 --input-format CasavaOneEightSingleLanePerSampleDirFmt \
 --output-path demux.qza

拆分区域数据

# P1
qiime cutadapt trim-paired \
--i-demultiplexed-sequences demux.qza \
--p-front-f TGGCGGACGGGTGAGTAA \
--p-front-r CTGCTGCCTCCCGTAGGA \
--p-discard-untrimmed \
--p-error-rate 0.15 \
--o-trimmed-sequences ./P1_demux.qza # P2
 qiime cutadapt trim-paired \
--i-demultiplexed-sequences demux.qza \
--p-front-f TCCTACGGGAGGCAGCAG \
--p-front-r  TATTACCGCGGCTGCTGG \
--p-discard-untrimmed \
--p-error-rate 0.15 \
--o-trimmed-sequences ./P2_demux.qza # P3
 qiime cutadapt trim-paired \
--i-demultiplexed-sequences demux.qza \
--p-front-f CAGCAGCCGCGGTAATAC \
--p-front-r  CGCATTTCACCGCTACAC \
--p-discard-untrimmed \
--p-error-rate 0.15 \
--o-trimmed-sequences ./P3_demux.qza # P4
 qiime cutadapt trim-paired \
--i-demultiplexed-sequences demux.qza \
--p-front-f AGGATTAGATACCCTGGT \
--p-front-r  GAATTAAACCACATGCTC \
--p-discard-untrimmed \
--p-error-rate 0.15 \
--o-trimmed-sequences ./P4_demux.qza # P5
 qiime cutadapt trim-paired \
--i-demultiplexed-sequences demux.qza \
--p-front-f GCACAAGCGGTGGAGCAT \
--p-front-r  CGCTCGTTGCGGGACTTA \
--p-discard-untrimmed \
--p-error-rate 0.15 \
--o-trimmed-sequences ./P5_demux.qza # P6
 qiime cutadapt trim-paired \
--i-demultiplexed-sequences demux.qza \
--p-front-f AGGAAGGTGGGGATGACG \
--p-front-r  CCCGGGAACGTATTCACC \
--p-discard-untrimmed \
--p-error-rate 0.15 \
--o-trimmed-sequences ./P6_demux.qza

从得到的数据看,各个区域的数据分布不是太一致,是不是多重PCR做的,引物偏好性有一定影响,所以这里面的影响也值得思考哈。

-rw-r--r-- 1 zjd zjd 2.6M Jan 31 11:00 P1_demux.qza
-rw-r--r-- 1 zjd zjd 466K Jan 31 11:32 P2_demux.qza
-rw-r--r-- 1 zjd zjd  13M Jan 31 11:33 P3_demux.qza
-rw-r--r-- 1 zjd zjd  11M Jan 31 11:34 P4_demux.qza
-rw-r--r-- 1 zjd zjd 3.5M Jan 31 11:34 P5_demux.qza
-rw-r--r-- 1 zjd zjd  22M Jan 31 11:35 P6_demux.qza

去噪

这里发现官方推荐的两去噪方法均报错呢,于是用了qiime2 vsearch解决。

# ########
# Vsearch
###########
 for i in {1..6}
do
 qiime vsearch join-pairs \
 --i-demultiplexed-seqs P${i}_demux.qza \
 --o-joined-sequences P${i}_demux-joined.qzatime qiime quality-filter q-score \
 --i-demux P${i}_demux-joined.qza \
 --o-filtered-sequences P${i}_demux-joined-filtered.qza \
 --o-filter-stats P${i}_demux-joined-filter-stats.qza
qiime vsearch dereplicate-sequences \
 --i-sequences P${i}_demux-joined-filtered.qza \
 --o-dereplicated-table P${i}_table.qza \
 --o-dereplicated-sequences P${i}_rep-seqs.qzaecho vsearch denovo startdate#denovo pick otuqiime vsearch cluster-features-de-novo \
 --i-table P${i}_table.qza \
 --i-sequences P${i}_rep-seqs.qza \
 --p-perc-identity 0.99 \
 --o-clustered-table P${i}_table-dn-99.qza \
 --o-clustered-sequences P${i}_rep-seqs-dn-99.qza
 echo vsearch end
 done

以下是我走过的弯路(可以略过):
dada2和deblur,两个算法,习惯于用第一个啦,遗憾报错,换了个2020.2月版本依然,上后者。

#dada2for i in {1..6}
do
qiime dada2 denoise-paired \
 --i-demultiplexed-seqs P${i}_demux.qza \
 --p-trim-left-f 0 \
 --p-trim-left-r 0 \
 --p-trunc-len-f 0 \
 --p-trunc-len-r 0 \
 --o-table ${i}_table.qza \
 --o-representative-sequences P${i}_rep-seqs.qza \
 --o-denoising-stats P${i}_denoising-stats.qza done
# Plugin error from dada2:
# An error was encountered while running DADA2 in R (return code 1), please inspect stdout and stderr to learn more.# Debug info has been saved to /tmp/qiime2-q2cli-err-wqromfhv.log12345678910111213141516

deblur

 ##############选项2,deblur,耗时也较长# 序列质控6152.75s
for i in {1..6}
do
qiime vsearch join-pairs \
 --i-demultiplexed-seqs P${i}_demux.qza \
 --o-joined-sequences P${i}_demux-joined.qzatime qiime quality-filter q-score \
 --i-demux P${i}_demux-joined.qza \
 --o-filtered-sequences P${i}_demux-joined-filtered.qza \
 --o-filter-stats P${i}_demux-joined-filter-stats.qza# # # deblur去噪生成特征表time qiime deblur denoise-16S \
 --i-demultiplexed-seqs P${i}_demux-joined.qza \
 --p-sample-stats \
 --o-representative-sequences P${i}_rep-seqs-deblur.qza \
 --o-table P${i}_table-deblur.qza \
 --o-stats P${i}_deblur-stats.qza done

time qiime deblur denoise-16S \
 --i-demultiplexed-seqs P1_demux-joined-filtered.qza \
 --p-trim-length 236 \
 --p-sample-stats \
 --o-representative-sequences P1_rep-seqs-deblur.qza \
 --o-table P1_table-deblur.qza \
 --o-stats P1_deblur-stats.qza

qiime sidle trim-dada2-posthoc \
--i-table table-dada2.qza \
--i-representative-sequences rep-seqs-dada2.qza \
--p-trim-length 100 \
--o-trimmed-table table-dada2-100nt.qza \
--o-trimmed-representative-sequences rep-seq-dada2-100nt.qza

qiime demux summarize \
 --i-data P1_demux-joined.qza --o-visualization demux-subsample.qzv

继续前面的文档学习,地址地这里啦!官方文档
SMURF 算法的核心是基于基于 kmer 的短区域重建到全长框架中。有两个步骤,首先是ASV在单个区域基于kmer进行比对,然后完整的序列集组装成重建的计数表。

区域比对

第一步是每个区域把序列比对到数据库,使用 align-regional-kmers 命令,我们前面使用--kmer-db-fp选项设置了数据库,使用 --rep-seq-fp选项传递ASV序列,最后是区域定义,来自前面你给区域起的别名,要完全一致。比对是一个开心的可并行任务,我们可以通过多多线程提升性能(--p-n-workers参数)。

# 继续循环解决啦for i in {1..6}
doqiime sidle align-regional-kmers \
--i-kmers ../database/../database/sidle-db-P${i}-100nt-kmers.qza \
--i-rep-seq P${i}_rep-seq-100nt.qza \
--p-region P${i} \
--p-n-workers 4 \
--o-regional-alignment alignment/P${i}_align-map.qza
done

‎这将输出一个对齐文件和任何不会与数据库对齐的 ASV 序列,以保留您自己的记录。‎另外,你可以设置与参考序列不同的长度,使用--p-max-mismatch参数(2-130)ps.我有点怀疑这样做有没有问题呀!
‎您可能会发现,如果您有更长的 kmers,您可能需要相应地增加此参数。较低的(更严格的)值将增加丢弃的序列的数量,而较高的数字可能意味着您的匹配项质量较低。您可能会发现,如果您有更长的 kmers,您可能需要相应地增加此参数。较低的(更严格的)值将增加丢弃的序列的数量,数字越高可能意味着匹配项的质量越低。‎

表重建

这步里,首先,是区域片段重新比对到完整的数据库序列,然后相对丰度使用一个优化的步骤进行计算,最后生成重建的计数表。
per-nucleotide-error参数和maximum-mismatch参数,决定了比对和错配的比例,Ps.我的理解是过程中会产生错误累积。
min-abundance决定了要排队的数据库序列的最小丰度,这个参数在某种意义上取决于测序深度和你的偏好。
最后,还是可以通过多多线程提升性能(
--p-n-workers参数)。
下面就是重建命令了,有点长呀:

qiime sidle reconstruct-counts \
--p-region P1 \
 --i-kmer-map ../database/sidle-db-P1-100nt-map.qza \
 --i-regional-alignment P1_align-map.qza \
 --i-regional-table P1_table-100nt.qza \
--p-region P2 \
 --i-kmer-map ../database/sidle-db-P2-100nt-map.qza \
 --i-regional-alignment P2_align-map.qza\
 --i-regional-table P2_table-100nt.qza \
  --p-region P3 \
 --i-kmer-map ../database/sidle-db-P3-100nt-map.qza \
 --i-regional-alignment P3_align-map.qza \
 --i-regional-table P3_table-100nt.qza \
  --p-region P4 \
 --i-kmer-map ../database/sidle-db-P4-100nt-map.qza \
 --i-regional-alignment P4_align-map.qza \
 --i-regional-table P4_table-100nt.qza \
  --p-region P5 \
 --i-kmer-map ../database/sidle-db-P5-100nt-map.qza \
 --i-regional-alignment P5_align-map.qza \
 --i-regional-table P5_table-100nt.qza \
    --p-n-workers 8 \
--o-reconstructed-table league_table.qza \
--o-reconstruction-summary league_summary.qza \
--o-reconstruction-map league_map.qza

好像这步是超级消耗资源的,我设置了个8核心,资源消耗竟然是*5的,用上了全部40核心的资源。。。不过几分钟就结束了,那么如果设置1个核心,可能是需要8倍时间的。
该命令将生成一个计数表、一个包含有关映射到某个区域的数据库Kmer数量以及ASV ID的详细信息的文件,以及一个需要进行分类重建的映射。

#可视化看下
qiime feature-table summarize \
--i-table reconstruction/league_table.qza \
--o-visualization reconstruction/league_table.qzv

这里我是用了一个样本,133个汇总的feature(也就是以前的OTU),40598条等效数据库序列。
您会注意到一些功能ID包含|字符,例如,1764594|195532|4471854。这意味着这两个数据库的序列在重建过程中不能被解析,因此我们将该序列分配给这两个区域。重建中使用的区域越多,就越有可能准确地重建数据库序列。
第二个输出是summary。总结可以用来评估重建的质量;更多细节见SMURF文章
原稿。默认情况下,摘要会将退化kmer视为唯一序列;您可以使用count-degenerates参数更改行为;如果为false,则仅当kmer属于唯一参考序列时才会对其进行计数。您可以通过将元数据制表来查看摘要。

# 汇总摘要
qiime metadata tabulate \
--m-input-file league_summary.qza \
--o-visualization league_summary.qzv

几个V区的计数明细和汇总
几个V区的计数明细和汇总

物种重建

重建特征表之后,需要重建物种,特别的,如果多个数据库序列不能得到处理时。该功能获取重建过程中生成的数据库映射和与数据库相关联的分类,并返回重建的分类。
有三种可能,第一,有相同的全部物种分类信息;第二,在一些点上有区别;第三,前面一直相同,直到一个缺失。
相同的情况最简单,二取一即可。有些情况下,可能物种分类在高水平上(这里是种)会不一样,例如下面这个,这种情况下会取到属,而不是种。

1236    k__Bacteria; p__Firmictues; c__Clostridia; o__Clostridiales; f__Lachnospiraceae; g__Blautia; s__obeum
1237    k__Bacteria; p__Firmictues; c__Clostridia; o__Clostridiales; f__Lachnospiraceae; g__Roseburia; s__12

--database 参数允许选择一个数据库进行,如 greengenes, silva 或不提供。如果是greengenes 或 silva,一些专门的数据库清理将会自动进行,特别是缺失和不明处理参数。例如:

k__Bacteria; p__Proteobacteria; c__Gammaproteobacteria; o__Entrobacteriales; f__Enterobacteriaceae; g__; s__1

将会整理成:

k__Bacteria; p__Proteobacteria; c__Gammaproteobacteria; o__Entrobacteriales; f__Enterobacteriaceae; g__unsp. f. Enterobacteriaceae; s__unsp. f. Enterobacteriaceae1

这里我们用的是greengenes,

qiime sidle reconstruct-taxonomy \
--i-reconstruction-map league_map.qza \
--i-taxonomy 。../database/sidle-db-taxonomy.qza \
--p-database 'greengenes' \
--p-define-missing 'inherit' \
--o-reconstructed-taxonomy ./league_taxonomy.qza

进化树重建

最后一步便是重建进化树了,如果不能解析参考序列,则不能简单地从数据库继承系统发育树。因此,我们需要重建一个新的系统树。我们以两种方式处理序列:

  • 任何可以完全解析的数据库序列都可以保持其在参考树中的位置。

  • 无法解析的序列需要以某种方式进行处理。

我们可以随机选择一个序列来映射重建的区域。然而,当有几个序列组合在一起时,这可能不起作用。因此,如果我们不能解析数据库序列,我们可以从组合的数据中计算一个融合序列,在我们能够绘制的区域中提取它们,然后这些一致的序列可以被插入到使用SEPP或类似的系统发育参考主干中(必须使用相同的数据库版本)。

因此,第一步,对不能解析的序列重建共识序列,这一步官方教程的结果应该有问题,看报错信息进行了更正。

qiime sidle reconstruct-fragment-rep-seqs \
--p-region P1 \
 --i-kmer-map ../database/sidle-db-P1-100nt-map.qza \
--p-region P2 \
 --i-kmer-map ../database/sidle-db-P2-100nt-map.qza \
  --p-region P3 \
 --i-kmer-map ../database/sidle-db-P3-100nt-map.qza \
  --p-region P4 \
 --i-kmer-map ../database/sidle-db-P4-100nt-map.qza \
  --p-region P5 \
 --i-kmer-map ../database/sidle-db-P5-100nt-map.qza \
 --i-reconstruction-map league_map.qza \
 --i-reconstruction-summary league_summary.qza \
 --i-aligned-sequences ../database/sidle-db-aligned-sequences.qza \
 --o-representative-fragments league-rep-seq-fragments.qza

现在,我们可以将序列放入参考树中了,首先下载参考树:

wget  -O "sepp-refs-gg-13-8.qza" \ "https://data.qiime2.org/2020.11/common/sepp-refs-gg-13-8.qza"

然后,插入序列:

qiime fragment-insertion sepp \
--i-representative-sequences league-rep-seq-fragments.qza \
--i-reference-database sepp-refs-gg-13-8.qza \
--o-tree league-tree.qza \
--o-placements league-placements.qza

最后,就可以继续常规的qiime2分析流程了,多样性,统计等等,能不能用picrust2分析呢?或许也可以的。

好了,一波三折,终于完成了这个教程的学习,不得不说这个技术好像还不够成熟,特别是qiime2的这个插件。





https://wap.sciencenet.cn/blog-623545-1270944.html

上一篇:SMURF(5R)-Science封面文章使用的16S新流程(二)
下一篇:Kraken2 Vs qiime2 16S物种注释
收藏 IP: 112.20.84.*| 热度|

0

该博文允许注册用户评论 请点击登录 评论 (0 个评论)

数据加载中...

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2024-5-24 07:27

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部