GCCP5标准换算怎么用,麻烦举个例子证明沟通能力!

玩转 Windows 10 中的 Linux 子系统
-08%-15%-24%-35%44%-54%-60%-68%-79%-90%-92%-94%
在今年的 Build 2016 上,微软向全世界他们还处于 Beta 阶段的&Windows 下的 Linux 子系统(Windows Subsystem for Linux)(WSL),它可以让开发者们在 Windows 10 下通过 Bash shell 运行原生的 Ubuntu 用户态二进制程序。如果你参与了 Windows Insider 计划,你就可以在最新的 Windows 10 年度升级版的 Insider 构建版中体验这个功能了。
Web 开发人员们不用再苦恼所用的 Windows 开发平台上没有合适的 Linux 工具和库了。WSL 是由 Windows 内核团队与 Canonical 合作设计和开发的,可以让 Windows 10 下的开发者们在拥有 Windows 中那些强力支持之外,还能使用 Linux 下丰富的开发环境与工具,而不用启动到另外的操作系统或者使用虚拟机。这绝对是一个&来自开发者,服务开发者&的 Windows 10 特色,它的目的是让开发者们每天的开发工作都变得顺畅而便捷。
在本文中,我会展示给你一些我认为非常有趣的功能,以及告诉你一些可以让你找到更多信息的资源。首先,我会展示 WSL 所集成的那些主要命令(比如 ssh)是如何操作服务器和设备的。其次,我会演示使用 Bash 脚本是如何以简明的方式来自动化执行任务的。其三,我会利用极棒的命令行编译器、一些其它工具以及对 *nix 兼容的能力来玩一个轻量级的古典黑客级游戏: NetHack。最后,我会展示如何使用已有的 Python 脚本和其它来自网上的脚本。
从我的第一台 286 上运行的 Windows 3.0 开始,Windows 就一直是我的主要操作系统和开发环境。不过,我身边也有很多 Linux 服务器和设备。从树莓派和路由器/网关设备这样的物联网设备,到 Minecraft 服务器,它们堆满了我的办公室的每个角落。而我经常要从我的主工作站中去管理和配置这些 Linux 计算机。
管理服务器和设备
我在我的家中运行着一台无显示器的 Ubuntu Minecraft 服务器,这是我去年给我十岁大的儿子的圣诞礼物,但是它已经变成了我的玩具而不是他的(好吧,主要是我的玩具)。我以前在我的 Windows 10 电脑上使用几个客户端来管理它,不过我现在想使用 Windows 中的 Bash 里面的 ssh 命令行来管理它。使用类似 PuTTY 或来自 Cygwin 的 Tera Term 这样的应用当然也可以,但是我想试试真正原生而自然的体验也是一种不错的选择。Cygwin 就像是在披萨店订购的披萨一样,好吃,但是没有那种氛围。
我已经使用 WSL 中的 ssh-keygen 和 ssh-copy-id 设置好了公私密钥对,所以使用 ssh 只需要如下简单输入即可:
$ ssh &username&@&server&
我还为此创建了一个别名,以便更快一些。这是一个标准的 Linux/Bash 功能:
$ alias mc='ssh &user&@&server&'
现在,我要访问我的 Minecraft 服务器只需要在 Windows 10 下的 Bash 中输入&mc&即可。
当然,同样的方法你也可以用于任何 Linux 上的 Web 或数据库服务器上,甚至树莓派或其它的物联网设备也可以。&
在终端里面进行 ssh 只是为了方便而已,不过当你在 shell 中工作时,如果还有类似 apt、node、Ruby、Python 等等工具时,你就有了自动化各种工作的可能。
假如说你有一大堆 Linux 服务器和设备,而你要在它们上面执行一个远程命令的话,如果已经配置好公私密钥对,你就可以在 Bash 中直接远程执行命令。
举个例子说,想知道远程服务器自从上次重启后已经运行了多长时间了,你只需要输入:
$ ssh &user&@&server& 'last -x|grep reboot'
ssh 会连接到该服务器并执行 last -x 命令,然后搜索包含&reboot&的一行。我在我的 Ubuntu Minecraft 服务器上运行的结果如下:
reboot&& system boot& 4.4.0-28-generic Thu Jul& 7 08:14&& still running
这只是一台服务器,如果你有许多服务器的话,你可以自动化这个过程。我在 WSL 里我的主目录下创建了一个名为 servers.txt 的文件,它包含了一系列 Linux 服务器/设备的名称,每个一行。然后我就可以创建一个脚本来读取这个文件。
在使用了很多年像树莓派这样的设备之后,我已经变成了一个 nano 人(在 VMS 上我是一个 LSEdit 人),下面是我用我喜爱的 nano 编辑器打开的脚本。
当然,你也可以使用 vim 、 emacs 或者其它可以用在 Ubuntu 终端上的编辑器。
该脚本是 Bash 脚本,要执行该脚本,输入:
$ ./foreachserver.sh 'last -x|grep reboot'
它将迭代输出文件中的每个服务器/设备,然后通过 ssh 远程执行该命令。当然,这个例子非常简单,但是你可以像这样把你的本地脚本或其它命令变成远程的。Bash 脚本语言足够丰富,所以你可以使用它来完成你的大多数远程管理任务。你可以用你下载到 WSL 或远程系统中的其它应用来扩展它的使用。
你是否需要在工作中把本地的 Windows 文件或资源用于其它的 Linux 计算机吗?或者,你根本不使用 Linux ?Bash 可以操作本地的 Windows 文件或资源,还是说它就是一个完全独立的环境?
使用 Windows 文件
WSL 系统可以通过&/mnt/&盘号&/ 目录(挂载点)来访问你计算机上的文件系统。举个例子,你的 Windows 上的 C:\ 和 D:\ 根目录可以在 WSL 中相应地通过 /mnt/c 和 /mnt/d 访问。当你要把你的 Windows 下的项目文件、下载的内容和其它文件用到 Linux/Bash 之中时这很有用。
上图显示的两个目录分别对应于我的计算机上的 SSD 和硬盘:
这是逻辑挂载,所以当你在 shell 中使用类似 mount 这样的命令时它们不会显示。但是它们可以如你预期的那样工作。举个例子,在 Windows 中,我在我的 C 盘根目录下放了一个名为 test.txt 的文件,我可以在 WSL 中如下访问它:&
在 Build &Tour 大会期间,我们要确保所有的演示都可以在没有互联网时也能正常工作(你绝不会知道会场的网络是什么样子的) ,所以为了让 Bash/WSL 可以演示 Git 操作,该演示访问的是本地计算机上的 Windows 文件,我在 Windows 上的 C:\git\NetHack 下设置一个本地仓库。 要在 WSL 中进行 clone 操作,我执行了如下命令:
$ git &clone file:///mnt/c/git/NetHack
该命令告诉 git 使用 file://&协议,并 clone 了位于&/mnt/c/git/NetHack 下的仓库。你可以以类似的方式来访问你的 Windows 下的所有文件。
警示:就像在其它终端中一样,如果你不小心的话,你可以在 Bash 中修改/删除 Windows 文件系统中的文件。举个例子,你可以像下面这样来干掉你的 Windows ,假如你有合适的权限的话。
$ rm -rf /mnt/c/
[千万别试!][千万别试!][千万别试!]
我之所以郑重提醒是因为我们很多人都是刚刚接触 Linux 命令,它们不是 Windows 命令。
这种可以让文件系统集成到一起的魔法来自 DrvFs。如果你希望了解该文件系统的更多细节,以及它是如何工作在 WSL 中的,WSL 团队为此写了一篇。
当然, 文件系统访问只是 WSL 其中的一部分功能而已,许多开发任务还需要通过 HTTP 或其它网络协议访问远程资源。
发起 HTTP 请求
从脚本或命令行而不是从一个编译好的程序或 Web 页面上发起 REST 或其它 HTTP(或 FTP)请求是很有用的。就像在大多数 Linux 发行版一样,WSL 也包括了类似 curl 或 wget 获取资源这样的标准功能,它们可以用来发起 HTTP 或者其它网络请求。举个例子,下面是使用 curl 对 Github 发起 REST 请求来获取我个人的属性信息:
$ curl -i https://api.github.com/users/Psychlist1972
HTTP/1.1 200 OK
Server: GitHub.com
Date: Wed, 13 Jul :08 GMT
Content-Type: application/ charset=utf-8
Content-Length: 1319
Status: 200 OK
"login": "Psychlist1972",
"avatar_url": "https://avatars.githubusercontent.com/u/1421146?v=3",
"url": "https://api.github.com/users/Psychlist1972",
"name": "Pete Brown",
"company": "Microsoft",
你可以用它和 Bash 脚本来创建一个 REST API 的快速测试客户端,也可以用来探测一个 Web 页面或服务器并报告其返回的状态。它用来从网上下载文件也很棒,你可以简单地重定向输出到一个文件而不是在屏幕上显示它:
$ curl -i https://api.github.com/users/Psychlist1972 & pete.json
我也是一个 PowerShell 用户,甚至还使用&&创建了一些有趣的扩展,也过出现在特定的录音硬件设备上的一些文件问题。作为长时间的 .NET 开发者和爱好者,我经常使用和扩展 PowerShell 以满足我的项目需求。但是 &PowerShell 并不是一个可以运行所有的那些 Bash 脚本和针对 Linux 的开源工具的地方。我希望以一种最简单、最舒服的方式来完成这些任务,在某种意义上,这意味着我们需要在 Bash 中完成它们。
我已经一掠而过的介绍了 Bash、Bash 脚本以及你可以在 shell 中完成的任务。到目前为止,我谈论的都是有助于开发工作的那些功能。但是在 WSL 中实际的开发和编译工作是怎样的?我在 Build Tour 大会上演示了下面这个部分。
Build Tour 大会上的演示:NetHack
这个夏初,来自微软的讲演者们向大家演示了一些来自 Windows 和微软云上的很酷的开发者新功能。作为其中的一部分,我以一种好玩的方式来演示了 WSL,而且这是一种和开发者们相关的方式。
我个人想要展示使用 git 和一些传统的终端开发工具,我已经写好了 Bash 的演示程序,包括了这些基础的东西(用 Python 和 Ruby 写的&Hello World&),不过我还是想要更有冲击力一些。
我回想起我在大学的时光,那时我们在 Unix(DEC Ultrix 及 SunOS)和 VAX/VMS 之间折腾,Unix 几乎全是命令行环境。在我们学校,绝大多数使用图形工作站的用户只是为了在不同的窗口打开多个终端会话而已,当然,会在桌面背景放上一张超酷的月相图。大部分学生都是使用 VT-220 终端来打开他们的会话(学校离波士顿不远,所以我们有很多 DEC 设备)。
那时,计算机系的学生们主要玩两大游戏:MUD (主要是 lpMUD 和当时刚出的 DikuMUD)和&。NetHack 和其它的&&类游戏被视为历史上最有影响力的游戏之一,它们是许多现在流行的地牢冒险和角色扮演类游戏的鼻祖。
NetHack 有很长的历史,现在的它包含了来自几十年前的几十万行 *nix 代码,以及后来补充的一些代码。该游戏使用&&(及其替代品)作为终端交互方式,需要通过 lex、&yacc(或 flex 和 bison)和 cc(或 gcc),以及一堆其它的开发工具构建。
它是由 C 语言编写的,并包括了一些用&&编写的复杂的脚本配置功能。我觉得它是一个体现 WSL 和 Bash on Windows 10 的开发者能力的不错而有趣的方式。由于使用了 curses(在 Linux 和 WSL 中是 libncurses 库),它也可以用来展示 Windows 10 中命令行窗口中的终端模拟能力。
以前,在我们的分时 Ultrix 服务器上从源代码构建 NetHack 要花费掉我们很多时间,而现在我的个人计算机上只需要几分钟就可以搞定。我喜欢这种技术进步。在 Linux 或 WSL 上配置和编译 NetHack 有容易和复杂两种方式。为了节省时间,我们会以容易的方式来进行。
首先,更新你的 WSL 环境,确保你的软件是最新的。在安装新的软件包之前,这是一个好的做法。
$ sudo apt update
$ sudo apt upgrade
然后,安装必须的开发工具。最简单的办法就是使用 build-essential 软件包,它包括了 Linux 开发者构建以 C/C++ 开发的软件时所需的绝大部分程序。
$ sudo apt install build-essential
这要花几分钟。如果你想更加深入地了解,你可以分别安装 gcc、gdb、make、flex、bison 以及 NetHack 文档中提到的其它工具。不过如果你是一位开发者,有时候你可能还需要一些其它工具。&build-essential 基本上提供了你所需的工具集。
然后,安装 git。如你所想,很容易:
$ sudo apt install git
就像在 Linux 中一样,你可以添加一个 git 的 PPA 来获取较新的版本,不过这里我们有一个就行了。
最后,我们需要安装 curses(实际上是 ncurses)来进行终端屏幕交互。
$ sudo apt install libncurses-dev
当我们完成这些步骤之后,就可以开始构建 NetHack 了。
构建 NetHack
官方的 NetHack 仓库放在 &上,首先我们需要把它抓取下来放到我们的主目录里面。
$ cd ~$ git clone http://github.com/NetHack/NetHack
因为 NetHack 支持很多种操作系统,所以我们需要做一些基础配置来告诉它我们使用的是 Linux,并且用开源的 gcc 代替了了&Unix 上 cc 的作用。
如我所提到的,这有好几种办法可以实现。有些人想很周到,将这些配置信息放到了 hints 文件中。相信我,使用 hints 文件会避免遇到该 GitHub 仓库中提到的很多麻烦。在 README 文件和其它文档中并没有着重提到如何使用 hints 文件,我们可以这样做:
$ cd NetHack/sys/unix
$ ./setup.sh hints/linux
这将会设置 Makefile 正确的使用 Linux 下的工具、库及其路径。这个设置脚本很强大,它做了大量的配置工作,很高兴它在 WSL 中工作的也很好。如果你很好奇这个脚本是如何写的,你可以使用你的编辑器打开它一窥究竟。
然后,开始最终的构建:
$ cd ~/NetHack
$ make all
构建完成之后,你需要安装它。这其实就是将可执行文件复制到目标位置:
$ make install
它会安装到你的&~/nh 文件夹下, NetHack 放在&~/nh/install/games 目录,名为 nethack。要运行它,切换到该目录(或输入完整路径)并输入:
$ cd ~/nh/install/games
然后,屏幕会清屏并显示你可以玩 NetHack 了。注意,所有的东西都是在这个 Ubuntu Linux 环境中完成的,根本不需要任何 Windows 特有的东西。
玩 NetHack
由于终端游戏的局限性和 NetHack 的复杂性,这里只能一带而过。对于初次接触它的人来说,还有一些神秘的地方,不过我觉得我们程序员们从来不怕挑战未知。
方向键和 vi(vim)中的一样,HJKL 是左、下、上、右。要退出游戏,你可以在地下城顶层找到楼梯出口然后使用它就可以,或者直接按下 CTRL-C 强制退出。
在 NetHack 中, @ 符号代表你自己,每一层都由房间、走廊、门,和向上及向下的楼梯组成。、以各种 ASCII &字符组成,你慢慢就会熟悉它们。为了符合&Roguelikes 游戏规范,并没有存盘功能,你只有一条命。如果你死了就只能重玩,地下城环境是随机生成的,各种物品也是打乱放置的。
NetHack 游戏的目的是在地下城生存,收集金子和物品,尽可能的干掉各种怪物。除了这些目的之外,你就是不断在其中玩来找它们。规则大致遵循&龙与地下城(DnD)&的武器、技能等规则。
下面的 NetHack 截屏上可以看到有三个房间和两个走廊。向上的楼梯在左上角的房间里,我现在在右上角的房间,还有一些宝箱和其它物品。
如果在你的游戏中没有显示颜色,可以创建一个名为&~/.nethackrc 的文件,并放入如下内容:
OPTIONS=color:true,dark_room:true,menucolors:true
注:如果 ASCII 字符图形不是你的菜,但是你喜欢这种类型的游戏,你可以在微软商店搜索&roguelike&来找到视觉上更好看的这种游戏。
当然,NetHack 很古老了,可能只有特定年龄段的人们喜欢它。不过,构建它用到了大量重要的开发工具和 *nix 操作系统功能,也包括终端模拟功能。从这里可以看到,从 gcc、gdb、make、bison 和 flex 到更现代一些的 git,都在 WSL 里面工作的很好。
如果你想看看 Build Tour 大会上的演示,你可以在 Build Tour 加拿大大会上看到这个讲演。WSL 的这部分演示在 6:20 开始。
希望你能喜欢在 NetHack 地下城中的探险。
C 和 C++ 都很伟大,就像其他的那些经典的开发工具一样。你甚至还可以用普通的 Bash 脚本做到很多。不过,也有很多开发者喜欢用 Python 做为他们的脚本语言。
你可以在网上找到很多 Python 脚本的例子,这意味着 Python 越来越流行,也越来越有用了。当然,大多数情况下这些例子都是运行在 Linux 下的。在过去,这就需要我们有另外一台安装着 Linux 的机器来运行它们,或者使用虚拟机和多引导,否则就需要修改一些东西才能让他们运行在 Windows 下的&Python 环境中。
这是都不是无法解决的问题,但是它会日渐消磨开发人员每天的生活。通过 WSL,不用折腾你就拥有了一个兼容的、具有 Python 功能和 shell 变量的子系统。
要安装最新的 Python 开发版本和 Python 包安装器 pip,在 Bash 中执行如下命令:
$ sudo apt install python-pip python-dev
$ sudo pip install --upgrade pip
现在 Python 安装好了,我要展示给你如何从网上获取一个典型的 Linux 下的 Python 例子并让它直接工作起来。我去&找一个排名第一的 Python 例子。好吧,我走眼了,排名第一的是打印出整数名称的脚本,这看起来没啥意思,所以我选择了第二名:俄罗斯方块。我们每天都能看到 Python 出现在各种地方,所以这次让我们去玩另外一个游戏。
我打开了 nano 编辑器,从 Windows 上的浏览器中打开的页面上复制了这 275 行 Python 代码,然后粘贴到我的 WSL 终端窗口终端中的 nano 中,并保存为 tetris.py ,然后执行它:&
$ python tetris.py
它马上就清屏并出现了俄罗斯方块的游戏。同 NetHack 一样,你可以使用同样的 vi 标准的方向键来移动(以前是使用鼠标和 WSAD 键来移动,而右手使用 HJKL 键更方便)。&
如我所提到的,你当然可以不用 WSL 就在 Windows 中运行 Python。然而,要想快速简便,不用修改 Linux 下的 Python 代码,只需要简单的复制粘贴代码即可运行,则可以极大的提高开发者的效率。
这是真的。这并不是要替代 Windows 原生的工具,比如 Python、PowerShell、C# 等等,而是当你需要在现代的开发工作流程中快速而有效地完成一些事情时,可以避免种种折腾。
包括 Bash、Python 以及其它所有的 Linux 原生的命令行开发工具,WSL 为我的开发工作提供了所有需要的工具。这不是一个 Linux 服务器,甚至也不是一个完整的客户端,相反,它就是一个可以让我避免每天折腾,让我在 Windows 上开发更有效率、更有快感的一个东西!
重置你的 WSL 环境
随便去试吧,如果你搞坏了你的 WSL 环境,它很容易重新安装。在进行之前,请确保做好了任何重要内容的备份。
C:\& lxrun.exe /uninstall /full
C:\& lxrun.exe /install
你使用 Bash 和 WSL 的感觉如何?
我们希望 WSL ,特别是 Bash 可以在 Windows 10 中帮你带来更高的效率,减少每天的开发中的折腾。
你对 Windows 10 上的 WSL 怎么看?你喜欢使用它吗?
开发团队做了大量的工作希望让 WSL 成为一个为开发者提供的强大的终端工具。如果你有任何反馈或运行出现问题,我们推荐你查看一下 ,以及&。我们真的希望听到你的声音。
更多参考与延伸阅读
Linux shell 编程是一个庞大的话题,在网上有很多这方面的内容。如果你还不够熟悉它们,想要了解更多,可以看看各种 Bash 教程。。
还有一些其他的参考资料也许对你有用:
哦,当然,要更多的了解 NetHack,请访问&。
上一篇:下一篇:
评论功能关闭
根据国家法律法规要求,本站暂时关闭文章评论功能。开放时间不确定。我们将谋求一种可以让大家更好的发表意见的方式。
根据国家法律法规要求,只有实名认证后才可以发表评论。
09:54 的评论:
作为一个没用过windows上的阉割版linux的人,我想问下你们使用的感受是什么?谢谢~
用虚拟机的感受会好些(就这么多)
共计翻译: 223 篇
| 共计贡献: 1351 天
贡献时间: -&
首先,我会展示 WSL 所集成的那些主要命令(比如 ssh)是如何操作服务器和设备的。其次,我会演示使用 Bash 脚本是如何以简明的方式来自动化执行任务的。其三,我会利用极棒的命令行编译器、一些其它工具以及对 *nix 兼容的能力来玩一个轻量级的古典黑客级游戏: NetHack。最后,我会展示如何使用已有的 Python 脚本和其它来自网上的脚本。
分享到微信
打开微信,点击顶部的“╋”,
使用“扫一扫”将网页分享至微信。
请将我们加入您的广告过滤器的白名单,请支持开源站点。谢谢您。豆丁微信公众号
君,已阅读到文档的结尾了呢~~
广联达云计价平台GCCP5--支持营改增解决方案
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
广联达云计价平台GCCP5--支持营改增解决方案
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='http://www.docin.com/DocinViewer--144.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口标准C++怎么实现对MSSQL的访问啊???最好是给我一个例子!!
[问题点数:0分]
标准C++怎么实现对MSSQL的访问啊???最好是给我一个例子!!
[问题点数:0分]
只显示楼主
取消只显示楼主
匿名用户不能发表回复!|技术追求准确,态度积极向上&figure&&img src=&https://pic4.zhimg.com/v2-da2f01dfcd8c4a5c411e073_b.jpg& data-rawwidth=&900& data-rawheight=&675& class=&origin_image zh-lightbox-thumb& width=&900& data-original=&https://pic4.zhimg.com/v2-da2f01dfcd8c4a5c411e073_r.jpg&&&/figure&&p&在第4节开始之前,先来一段插曲。在上一节中,我们说到可以使用Trimmomatic、sickle、seqtk或者SOAPnuke对fastq数据进行过滤。那么也许你会好奇,那他们都有什么特点,都一样好吗或是有哪些差异之处?正所谓,工欲善其事必先利其器,所以这篇文章将会与你一起来解开这几个问题。&/p&&p&因为Trimmomatic的安装已经在&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&第3节 数据质控&/a&说的比较清楚了,这里就不再赘述。那么,先说SOAPnuke的安装,你有两种方式:&/p&&figure&&img src=&https://pic4.zhimg.com/v2-4b0cdaad85ed7a2ee8f8f4_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&90& data-rawheight=&84& class=&content_image& width=&90&&&/figure&&p&第一,确保你的系统中有automake。由于SOAPnuke还使用了多个第三方的c++ 程序库,包括&b&但不限于&/b&: boost,log4cplus和openssl。因此,需要在你的系统中先安装好这几个库,并修改SOAPnuke代码包的CMakeLists.txt,重新指定里面这几个程序包的路径。同时还需要把上述包的include目录链接到CMakeList.txt中指定的目录(或者你也可以修改到其他目录)下。此外,如果上述三个包的静态库没在默认路径下,那么。。。你还得找到它们,然后修改路径,并涉及到少量代码的修改,再进行编译,然后祈祷。。。至于第三方程序库的安装方法都可以在网上找到。但特别指出一点,建议使用源码安装(特别是log4cplus),防止有些包默认不产生静态链接库。另外,版本不对也会报各种error,包括编译器的error,这里就不一一展开了。总之,如果没有一波N折.......那真是有鬼了,继续祈祷,祝你成功。&/p&&p&第二种,在公众号后台回复SOAPnuke,提供&b&编!译!好!的!可执行版本(&/b&Linux&b&)&/b&给大家,另外还包含了本系列中使用到的数据和相关代码(更新中),你值得拥有。&/p&&figure&&img src=&https://pic2.zhimg.com/v2-1c419eadcfdb0cfe5679c_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&146& data-rawheight=&140& class=&content_image& width=&146&&&/figure&&p&接着,安装另外两个适合用来切除read末尾低质量碱基的软件:&a href=&https://link.zhihu.com/?target=https%3A//github.com/najoshi/sickle& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&sickle&/a&和&a href=&https://link.zhihu.com/?target=https%3A//github.com/lh3/seqtk& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&seqtk&/a&。其中seqtk是bwa和samtools的作者Heng Li所编写的fq/fa序列处理工具,修剪read末尾低碱基只是其中一个功能(还包含了其他几个有用的功能);sickle比较专注,就只干低质量碱基切除这个事。这两个软件的安装都非常容易,可以直接从github上将源码下载下来编译,如果你用的是Mac电脑上还可以直接通过Homebrew安装,如:&/p&&div class=&highlight&&&pre&&code class=&language-bash&&&span&&/span&$ brew install sickle
$ brew install seqtk
&/code&&/pre&&/div&&p&这四个工具都安装完成之后,我们就可以开始了。下面我以&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&第2节&/a&提到的untreated.fq为例子。&/p&&p&&br&&/p&&p&为了适合做比较,如无特殊说明,我们都以相同的标准对数据进行过滤。&/p&&p&首先是Trimmomatic:&/p&&div class=&highlight&&&pre&&code class=&language-bash&&&span&&/span&$ java -jar trimmomatic-0.36.jar SE -phred33 &span class=&se&&\&/span&
-trimlog untreated.logfile &span class=&se&&\&/span&
raw_data/untreated.fq u.trimmomatic.fq
SLIDINGWINDOW:5:20 LEADING:5 TRAILING:5 MINLEN:20
&/code&&/pre&&/div&&p&由于untreated.fq只有一份文件,就当作是Single End测序的数据来对待,因此我选择SE模式。质量值体系选择-phred33。这里再强调一次,&b&目前基本上所有的NGS测序数据都是Phred33质量值体系,包括illumina HiSeq X10、NovaSeq等所有HiSeq 2500 之后(包括HiSeq 2500)推出的测序平台&/b&;质量判定窗口长度设定为5,窗口中碱基平均质量阈值为20(SLIDINGWINDOW:5:20);read首尾碱基切除的质量阈值为5(LEADING:5 TRAILING:5);过滤后最小read长度为20bp,如果低于则丢弃。&/p&&p&然后是SOAPnuke,这个和Trimmomatic一样,能够通过局部比对去除fq序列中测到的adapter序列,但是不会切除read末端低质量序列,而是通过设定低质量碱基数目比例的阈值来进行过滤。它的这种过滤方法有一定的缺陷,我们下文会说到。现在我们先完成例子:&/p&&div class=&highlight&&&pre&&code class=&language-bash&&&span&&/span&$ SOAPnuke1.5.6 filter -l &span class=&m&&20&/span& -G -Q &span class=&m&&2&/span& -1 untreated.fq -C u.soapnuke.fq.gz -o ./
&/code&&/pre&&/div&&p&SOAPnuke filter的参数是比较多的,我们这里挑其中几个最重要的来说说:&/p&&ul&&li&-l 判定低质量碱基的阈值,它默认是5。我们这里为了保持和Trimmomatic的一致,同样设置为20;&/li&&li&-G 参数,如果设置了就表示质量值体系选择为phred33,默认是phred64。这是一个值得注意的地方,因为在SOAPnuke中是用sanger和illumina这两个词来分别代表phred33和phred64质量体系的。之所以会这样其实开发该软件的历史原因,在比较早期的时候,phred33和phred64这两个词用的还比较少。开发人员知道的是sanger测序的质量值是ASCII-33,而illumina的质量值要-64(早期版本),因此为了好记,就直接用了这两个词,代表和sanger的一样,或者和illumina的一样;&/li&&li&-Q 参数用于指明我们过滤后输出的read要选用哪种质量值体系输出,1代表phred64,2代表phred33,默认依然是phred33。SOAPnuke中的文档用的也依然是illumina和sanger作为不同质量值体系的标识;&/li&&li&-1 参数用于接输入的read1,相应的还有一个 -2 参数,用于接入read2,这是对于Pair-End测序而言的,我们这里只有一个fq,因此使用 -1 就可以了。&/li&&li&-C是输出文件的名字。SOAPnuke总是会输出gz压缩的文件,如果文件名中没有.gz,那么会被自动加上,如果没有指定这个-C参数,那么输出的文件会在原来输入文件的前面加上Clean_前缀;&/li&&li&-o 参数用于指定输出目录,默认是当前程序的运行目录;我们这里指定为当前目录;&/li&&/ul&&p&SOAPnuke还有其它几个有用的参数,包括:-n代表一条read中可以允许多大比例的N;-d代表是否要去除PCR过程产生的重复序列,-q用于调整低质量碱基所占比例等等;此外,SOAPnuke还会在结果目录下同时输出其他几份文件,用于记录一下过滤前后的质量信息,由于本文中不会用到它们就不一一细说了。&/p&&p&&br&&/p&&p&接下来是sickle:&/p&&div class=&highlight&&&pre&&code class=&language-bash&&&span&&/span&$ sickle se -f raw_data/untreated.fq -t sanger -o u.sickle.fq
SE input file: raw_data/untreated.fq
Total FastQ records: 250000
FastQ records kept: 249742
FastQ records discarded: 258
&/code&&/pre&&/div&&p&这里的fastq输入文件通过 -f 参数传入,输出结果通过 -o 参数指定。需要重点注意的是 -t 参数,这里需要明确指定fastq具体的质量值体系(详见第2节)。sickle能够处理所有三种不同的质量值体系(solexa Phred64,illumina Phred64 和 Phred33,详见第2节),这里的sanger指的就是phred33,我认为这个叫法和SOAPnuke的质量值体系命名是一样的原因!&/p&&p&最后是seqtk,修剪低质量碱基的功能模块是 trimfq,默认情况下只需直接给定一个fastq输入文件就行了,结果会直接输出到屏幕,这里我们将其重定向到一份新的输出文件中:&/p&&div class=&highlight&&&pre&&code class=&language-bash&&&span&&/span&$ seqtk trimfq raw_data/untreated.fq & u.trimfq.fq
&/code&&/pre&&/div&&p&seqtk trimfq的功能比较单一,只能处理phred33,其他的都不行,参数很简洁。&/p&&blockquote&【注】sickle和seqtk trimfq都不能用于adapter序列的切除,它们没有这个功能。&/blockquote&&p&&br&&/p&&h2&&b&结果比较&/b&&/h2&&p&现在我们来比较一下这四个修剪之后的结果。由于数据比较少,这里我打算直接用R来完成这个任务,如果是比较大量的数据,还是建议用python/perl/java/c++/c等。&/p&&p&在开始之前,我们还需要再安装一个R包——qrqc来分析这个数据并进行画图可视化。qrqc是Bioconductor这个大包中的一个部分,适合用于我们这个任务的分析。它的安装也很容易,在终端运行R,然后输入以下语句即可,注意如果发现不支持&https://&的话,可以尝试使用“http://”:&/p&&div class=&highlight&&&pre&&code class=&language-bash&&&span&&/span&& source&span class=&o&&(&/span&&span class=&s2&&&https://bioconductor.org/biocLite.R&&/span&&span class=&o&&)&/span&
& biocLite&span class=&o&&(&/span&&span class=&s2&&&qrqc&&/span&&span class=&o&&)&/span&
&/code&&/pre&&/div&&p&这里我用qrqc包来分析read各个位置上的质量值分布情况,并用ggplot2将其展示出来,代码如下:&/p&&div class=&highlight&&&pre&&code class=&language-rconsole&&&span&&/span&&span class=&go&&library(qrqc)&/span&
&span class=&go&&# 指定fastq文件路径&/span&
&span class=&go&&fq_files = c(rawdata=&raw_data/untreated.fq&,&/span&
&span class=&go&&
trimmomatic=&u.trimmomatic.fq&,&/span&
&span class=&go&&
soapnuke=&u.soapnuke.fq&,&/span&
&span class=&go&&
sickle=&u.sickle.fq&,&/span&
&span class=&go&&
seqtk_trimfq=&u.trimfq.fq&)&/span&
&span class=&go&&# Load each fastq file in by using qrqc's readSeqFile&/span&
&span class=&go&&seq_read = lapply(fq_files, function(file) {&/span&
&span class=&go&&
readSeqFile(file, hash = FALSE, kmer = FALSE)&/span&
&span class=&go&&})&/span&
&span class=&go&&quals = mapply(function(sfq, name) {&/span&
&span class=&go&&
qs = getQual(sfq)&/span&
&span class=&go&&
qs$trimmer = name&/span&
&span class=&go&&
&span class=&go&&}, seq_read, names(fq_files), SIMPLIFY = FALSE)&/span&
&span class=&go&&d = do.call(rbind, quals)&/span&
&span class=&go&&# 画图&/span&
&span class=&go&&library(ggplot2)&/span&
&span class=&go&&position = d$position&/span&
&span class=&go&&mean = d$mean&/span&
&span class=&go&&trimmer = d$trimmer&/span&
&span class=&go&&p1 = qplot(position, mean, color=trimmer, geom=c(&line&, &point&))&/span&
&span class=&go&&# p1 = ggplot(d) + geom_line(aes(x=position, y=mean, linetype=trimmer))&/span&
&span class=&go&&# p1 = ggplot(d) + geom_line(aes(x=position, y=mean, color=trimmer))&/span&
&span class=&go&&p1 = p1 + ylab(&Mean quality (Phred33)&) + theme_bw()&/span&
&span class=&go&&print(p1)&/span&
&span class=&go&&p2 = qualPlot(seq_read, quartile.color = NULL, mean.color = NULL) + theme_bw()&/span&
&span class=&go&&p2 = p2 + scale_y_continuous(&Quality (Phred33)&)&/span&
&span class=&go&&print(p2)&/span&
&/code&&/pre&&/div&&p&这段代码接受五个输入文件,一份原始的fastq和其他4份修剪过后的fastq,并输出两幅图:图1和图2。在图1中,横轴是read的位置,纵轴是各位置上的平均质量值,我们可以看到越到read的末尾,质量会随着下降,特别是没做任何修剪的原始fastq,可以看出其末尾的碱基质量更差,这意味着错误率更高了。这里SOAPnuke比较亮。。。&/p&&figure&&img src=&https://pic1.zhimg.com/v2-63f7a70de8f_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1226& data-rawheight=&719& class=&origin_image zh-lightbox-thumb& width=&1226& data-original=&https://pic1.zhimg.com/v2-63f7a70de8f_r.jpg&&&/figure&&p&
图1. 平均质量值分布&/p&&p&在图2中,我们同时对比了这5份文件的质量值分布情况,可以看出,无论是用Trimmomatic、sickle还是seqtk我们都将read末尾的低质量碱基成片切除了,末端的质量值范围也会被我们限制在了较高的区域,这可以确保下游分析过程不会过多地被低质量碱基所干扰,然鹅SOAPnuke!!!&/p&&figure&&img src=&https://pic4.zhimg.com/v2-d9924eefda8bbd463713_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1196& data-rawheight=&694& class=&origin_image zh-lightbox-thumb& width=&1196& data-original=&https://pic4.zhimg.com/v2-d9924eefda8bbd463713_r.jpg&&&/figure&&p&
图2.质量值分布&/p&&h2&&b&小结&/b&&/h2&&p&毫无疑问,从上面的比较结果中,我们可以明显发现&b&,Trimmomatic最优,sickle次之,seqtk第三&/b&。当然,这其中结果最好的Trimmomatic丢弃掉的数据要比其他的略多(约1%~2%)。这三种里面比较特殊的是seqtk,它不丢弃任何read,只是将其截短,而且如果长度低于设定的最低read长度就不切除了,直接保留原数据。这也是为什么它相比于Trimmomatic和sickle而言质量要差的重要原因,可即便如此它们的结果其实相差并不多。反观SOAPnuke,虽然不愿意承认,但不得不说&b&SOAPnuke的过滤效果是最差的,几乎没什么效果&/b&。&/p&&figure&&img src=&https://pic1.zhimg.com/v2-f03512b8dcb31a328d8dabd3e49eb193_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1217& data-rawheight=&713& class=&origin_image zh-lightbox-thumb& width=&1217& data-original=&https://pic1.zhimg.com/v2-f03512b8dcb31a328d8dabd3e49eb193_r.jpg&&&/figure&&p&
图3. SOAPnuke 调节-q参数结果比较&/p&&p&这个图3中,我把SOAPnuke中低质量碱基占比的参数调得更加严格(20%)再和默认的50%相比,但发现改善其实并不特别明显。原因在于&b&SOAPnuke并不切除read的末端低质量序列,&/b&而只是通过判断当read中低质量的碱基比例达到一定程度的时候整个read去除。但这种情况其实是不合理的,因为根据目前的测序原理,read的错误率会明显富集于末端区域,而前半部分的质量都会比较高,这种计算比例的方法并不能很好地反映这一现象。虽然我们可以通过设置更严格的参数,比如图3将低质量值碱基的占比从50%降为20%来改善,lowQual也可以设置得更高一些,来获得一些改善。但我想说的是,这种差别的根本原因源自于对末端低质量碱基序列的处理,SOAPnuke这种整体性统计的方法,并不能有针对性地处理这些碱基。在实际的操作要花更多的时间和精力对参数进行对比(影响最大的参数是-q低质量碱基占比),这不是一个高明的手段,远不如其他三个通过滑动窗口计算局部质量值的方式来得直接和灵敏。&/p&&p&综上,如果需要同时去除测序接头序列,那么建议使用Trimmomatic;如果只需过滤低质量碱基或者低质量read,可以选择Trimmomatic或sickle,有时sickle会更快一些,如果不愿意read被过滤掉而且质量值体系是phred33,那么可以选择seqtk。&/p&&hr&&p&欢迎关注我的微信公众号:&b&解螺旋的矿工 &/b&更及时了解更多信息。&/p&&figure&&img src=&https://pic4.zhimg.com/v2-96f583d8d8ce4c16e60d74b58a34e68a_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&479& data-rawheight=&498& class=&origin_image zh-lightbox-thumb& width=&479& data-original=&https://pic4.zhimg.com/v2-96f583d8d8ce4c16e60d74b58a34e68a_r.jpg&&&/figure&&p&&/p&
在第4节开始之前,先来一段插曲。在上一节中,我们说到可以使用Trimmomatic、sickle、seqtk或者SOAPnuke对fastq数据进行过滤。那么也许你会好奇,那他们都有什么特点,都一样好吗或是有哪些差异之处?正所谓,工欲善其事必先利其器,所以这篇文章将会与你一…
&figure&&img src=&https://pic2.zhimg.com/v2-ad244dbb4f278eaa7558f_b.jpg& data-rawwidth=&1920& data-rawheight=&1080& class=&origin_image zh-lightbox-thumb& width=&1920& data-original=&https://pic2.zhimg.com/v2-ad244dbb4f278eaa7558f_r.jpg&&&/figure&&p&经过了第四节的长文,我想大家基本上已经知道了一个WGS流程该如何构建起来了吧。但在那一节中限于篇幅有两个很重要的文件我没能展开来讲,分别是:BAM和VCF文件。这篇我们先说BAM文件。&/p&&h2&&b&什么是BAM&/b&&/h2&&p&BAM是目前基因数据分析中最通用的比对数据存储格式,它既适合于短read也适合于长read,最长可以支持128Mbp的超大read!除了后缀是.bam之外,有些同学可能还会看到.cram,甚至.sam后缀的文件,其实它们一个是BAM的高压缩格式(.cram)——IO效率比原来的BAM要略差;另一个是BAM的纯文本格式(.sam)。当然格式都是一样的,因此为了描述上的清晰,我下面都统一用BAM。&/p&&h2&&b&BAM文件格式&/b&&/h2&&p&其实一开始它的名字是SAM(The Sequencing Alignment/Map Format的英文简称),第一次出现的时候,它是bwa比对软件的标准输出文件,但原生的SAM是纯文本文件,十分巨大(比如:一个人30x全基因组测序的sam大小超过600G),非常容易导致存储空间爆满!为了解决这个问题,bwa的开发者李恒(lh3)设计了一种比gz更加高效的压缩算法,对其进行压缩,这就是我们所说的BAM,它的文件大小差不多只有原来的1/6。&/p&&p&在2007年,NGS技术刚刚兴起之时,各类短序列比对软件层出不穷,输出格式也是各有特点,各家各有一套,并没有什么真正的标准可言,可以说那是一个谁都说我最好的时期。&/p&&figure&&img src=&https://pic2.zhimg.com/v2-3fef8d4bdaa3ad9c27965_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&161& data-rawheight=&202& class=&content_image& width=&161&&&/figure&&p&但逐渐的,研究者们发现BAM格式对Mapping信息的记录是最全面的,用起来也是最灵活的。bwa的作者还为BAM文件开发了一个非常好用的工具包——Samtools,使得人们对BAM文件的处理变得十分便利,拓展性也变得非常强,后来还有类似于IGV等专门支持BAM的工具也越来越多,因此它就逐渐成为了主流。&/p&&p&现在基本上所有的比对数据都是用BAM格式存储的,俨然已经成为了业内的默认标准。&/p&&p&在2013年,研究者们还专门将Samtools的处理核心剥离出来,并将其打包成为一个专门用于处理高通量数据的API——htslib,除了C语言版本之外还有Java和Python版本,这些在github上都能直接找到。后续许多与NGS数据处理有关的工具基本都会使用这个API进行相关功能的开发,可见其影响力。&/p&&p&ok,背景的介绍就先到此为止了,我们回归主题。下面这个图是我从一份刚刚完成比对的bam文件中截取出来的内容:&/p&&figure&&img src=&https://pic2.zhimg.com/v2-f38d77bc06f923de816af95c3ebb4e05_b.jpg& data-size=&normal& data-rawwidth=&1785& data-rawheight=&722& class=&origin_image zh-lightbox-thumb& width=&1785& data-original=&https://pic2.zhimg.com/v2-f38d77bc06f923de816af95c3ebb4e05_r.jpg&&&figcaption&BAM文件&/figcaption&&/figure&&p&由于屏幕所限,无法把全部的内容都包含进来,特别是header信息,贴在这里仅是为了让还没见过BAM文件的同学们能够对它有一个总体的感觉。&/p&&p&如果是SAM文件,同时你也熟悉linux操作的话,直接在linux终端用less打开即可(注意:不要试图在本地使用文本编辑器,如vim等直接打开文件,会撑死机子的),但如果我们要查看的是BAM,那么必须通过Samtools(可以到samtools的网站下载并安装)。&/p&&div class=&highlight&&&pre&&code class=&language-bash&&&span&&/span&$ less -SN in.sam
&span class=&c1&&# 打开sam文件&/span&
$ samtools view -h in.bam
&span class=&c1&&# 打开bam文件&/span&
&/code&&/pre&&/div&&p&BAM文件分为两个部分:header和record。这里额外说一句,许多NGS组学数据的存储格式都是由header和record两部分组成的。&/p&&p&以上例子,在samtools view中加上-h参数目的是为了同时把它的header输出出来,如果没有这个参数,那么header默认是不显示的。&/p&&figure&&img src=&https://pic1.zhimg.com/v2-a4bf3987e6cfd10328a4_b.jpg& data-size=&normal& data-rawwidth=&1918& data-rawheight=&958& class=&origin_image zh-lightbox-thumb& width=&1918& data-original=&https://pic1.zhimg.com/v2-a4bf3987e6cfd10328a4_r.jpg&&&figcaption&header&/figcaption&&/figure&&p&header内容不多,也不会太复杂,每一行都用‘@’ 符号开头,里面主要包含了版本信息,序列比对的参考序列信息,如果是标准工具(bwa,bowtie,picard)生成的BAM,&b&一般还会包含生成该份文件的参数信息(如上图),&/b&@&b&PG标签开头的那些&/b&。这里需要重点提一下的是header中的@RG也就是Read group信息,这是在做后续数据分析时专门用于区分不同样本的重要信息。&b&它的重要性还体现在,如果原来样本的测序深度比较深,一般会按照不同的lane分开比对,最后再合并在一起,那么这个时候你会在这个BAM文件中看到有多个RG,里面记录了不同的lane,甚至测序文库的信息,唯一不变的一定是SM的sample信息,这样合并后才能正确处理&/b&。&/p&&p&其实,关于这一点我在&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&上一篇文章&/a&中讲序列比对时的也特意强调了这些方面,不记得的同学们也可以翻看上一篇的相关内容。&/p&&p&&b&接下来重点要说的是BAM的核心:record&/b&(有时候也叫alignment section,即,&b&比对信息&/b&)。这是我们通常所说的序列比对内容,&b&每一行都是一条read比对信息&/b&,它的记录看起来是这样的:&/p&&figure&&img src=&https://pic2.zhimg.com/v2-33fc6b2f061bfa87a70a9_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1230& data-rawheight=&290& class=&origin_image zh-lightbox-thumb& width=&1230& data-original=&https://pic2.zhimg.com/v2-33fc6b2f061bfa87a70a9_r.jpg&&&/figure&&p&我这里借用了网上的一张图片来辅助说明,recoed中的每一个信息都是用制表符tab分开的。&/p&&p&下面我们就来仔细瞧瞧这里的每一个信息分别都是什么。&/p&&figure&&img src=&https://pic3.zhimg.com/v2-7cc23abc51a8bbddfaa96_b.jpg& data-size=&normal& data-rawwidth=&1363& data-rawheight=&837& class=&origin_image zh-lightbox-thumb& width=&1363& data-original=&https://pic3.zhimg.com/v2-7cc23abc51a8bbddfaa96_r.jpg&&&figcaption&BAM格式&/figcaption&&/figure&&p&以上,前11列是所有BAM文件中都必须要有的信息,而且从描述中我们也能够比较清楚地知道其所代表的含义。但其中,有几个信息实在太重要了,以至于我认为有必要对其进行详细说明。&/p&&p&&b&第一,Flag信息&/b&&/p&&p&这是一个非常特别并且重要的数字,也是一个容易被忽视的数字,这可能和许多生信工程师也并不完全理解这个值有关。许多同学在第一次看到其官方文档中的描述之后依然会觉得十分困惑,但它里面实际上记录了许多有关read比对情况的信息。&b&想要读懂它的一个关键点是我们不能够将其视为一个数字,而是必须将其转换为一串由0和1组成的二进制码,这一串二进制数中的每一个位(注意是“位”,bit的意思)都代表了一个特定信息,它一共有12位(以前只有8位),所以一般会用一个16位的整数来代表,这个整数的值就是12个0和1的组合计算得来的,因此它的数值范围是0~次方,计算机科学的同学对这种计算应该不陌生)&/b&。&/p&&p&那么下面我就结合其文档和自己的实践经验对这12个位的含义用更加通俗易懂的语言来重新描述,如下表:&/p&&figure&&img src=&https://pic1.zhimg.com/v2-bdc826f9e8b3a7ae8914_b.jpg& data-size=&normal& data-rawwidth=&1752& data-rawheight=&956& class=&origin_image zh-lightbox-thumb& width=&1752& data-original=&https://pic1.zhimg.com/v2-bdc826f9e8b3a7ae8914_r.jpg&&&figcaption&FLAG的含义&/figcaption&&/figure&&p&所以,通过上面这个表的信息,我们就可以清楚地知道每一个FLAG中都包含了什么信息。比如看到FLAG = 77时,我们第一步要做的就是将其分解为二进制序列(也可以理解为分解成若干个2的n次方之和):&/p&&p&77 =
= 1 + 4 + 8 +64,这样就得到了这个FLAG包含的意思:PE read,read比对不上参考序列,它的配对read也同样比不上参考序列,它是read1。&/p&&p&当然,如果你希望自己在程序中写一段处理FLAG的代码,那么显然是不会像我们这个例子那样去分解这个整数的,多麻烦啊!那么该如何做呢?其实也很简单,比如我们&b&要获得其中某个位(假设第N位)的值——只需要将这个FLAG值和2的N次方做与的运算即可。&/b&在与运算时,FLAG值首先会被转换成一串二进制序列(如77=),而2的N次方除了第N位是1之外,其它的都是0,“与”了之后其它信息就会被屏蔽掉。比如,我们想知道该read是否比对上了参考序列,那么只需要计算FLAG & 4 的值就行了,如果结果是1那么就是比对上了,如果是0则代表没有比上。&/p&&p&不过,在实际工作中,除非遇到特殊的情况,否则我一般更推荐调用官方的htslib这个包来协助处理,它是一个C语言库,如果你用Python,则是pysam——htslib的python包(Java则是htsjdk),包中已经帮我们做了这些处理,可以直接得到结果,下一篇文章里我会用pysam举例说明如何用它来操作bam文件。&/p&&p&另外,下面这一段代码是htslib(samtools的核心库)中定义的12个与flag值进行与操作获取对应位信息的变量,感兴趣的同学可以再htslib里面的sam.h文件中找到,在做一些需要触达基础性原理的开发时或许你会用到。&/p&&div class=&highlight&&&pre&&code class=&language-c&&&span&&/span&&span class=&cm&&/*! @abstract the read is paired in sequencing, no matter whether it is mapped in a pair */&/span&
&span class=&cp&&#define BAM_FPAIRED
&span class=&cm&&/*! @abstract the read is mapped in a proper pair */&/span&
&span class=&cp&&#define BAM_FPROPER_PAIR
&span class=&cm&&/*! @abstract the rea conflictive with BAM_FPROPER_PAIR */&/span&
&span class=&cp&&#define BAM_FUNMAP
&span class=&cm&&/*! @abstract the mate is unmapped */&/span&
&span class=&cp&&#define BAM_FMUNMAP
&span class=&cm&&/*! @abstract the read is mapped to the reverse strand */&/span&
&span class=&cp&&#define BAM_FREVERSE
&span class=&cm&&/*! @abstract the mate is mapped to the reverse strand */&/span&
&span class=&cp&&#define BAM_FMREVERSE
&span class=&cm&&/*! @abstract this is read1 */&/span&
&span class=&cp&&#define BAM_FREAD1
&span class=&cm&&/*! @abstract this is read2 */&/span&
&span class=&cp&&#define BAM_FREAD2
128&/span&
&span class=&cm&&/*! @abstract not primary alignment */&/span&
&span class=&cp&&#define BAM_FSECONDARY
256&/span&
&span class=&cm&&/*! @abstract QC failure */&/span&
&span class=&cp&&#define BAM_FQCFAIL
512&/span&
&span class=&cm&&/*! @abstract optical or PCR duplicate */&/span&
&span class=&cp&&#define BAM_FDUP
1024&/span&
&span class=&cm&&/*! @abstract supplementary alignment */&/span&
&span class=&cp&&#define BAM_FSUPPLEMENTARY 2048&/span&
&/code&&/pre&&/div&&p&&b&第二,CIGAR&/b&&/p&&p&CIGAR是&b&C&/b&ompact &b&I&/b&diosyncratic &b&G&/b&apped &b&A&/b&lignment &b&R&/b&eport的首字母缩写,称为“雪茄”字符串。&/p&&figure&&img src=&https://pic2.zhimg.com/v2-a65e9e80dc737c6d5f1fb8caff99a839_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&300& data-rawheight=&268& class=&content_image& width=&300&&&/figure&&p&&b&作为一个字符串,它用数字和几个字符的组合形象记录了read比对到参考序列上的细节情况,读起来要比FLAG直观友好许多,只是记录的是不同的信息。&/b&比如,一条150bp长的read比对到基因组之后,假如看到它的CIGAR字符串为:33S117M,其意思是说在比对的时候这条read开头的33bp在被跳过了(S),紧接其后的117bp则比对上了参考序列(M)。这里的S代表软跳过(Soft clip),M代表匹配(Match)。CIGAR的标记字符有“MIDNSHP=XB”这10个,分别代表read比对时的不同情况:&/p&&figure&&img src=&https://pic1.zhimg.com/v2-e984dcca1a4_b.jpg& data-size=&normal& data-rawwidth=&1532& data-rawheight=&664& class=&origin_image zh-lightbox-thumb& width=&1532& data-original=&https://pic1.zhimg.com/v2-e984dcca1a4_r.jpg&&&figcaption&CIGAR的含义&/figcaption&&/figure&&p&除了最后‘=XB’非常少见之外,其它的标记符通常都会在实际的BAM文件中碰到。另外,&b&对于M还是再强调一次,CIGAR中的M,不能觉得它代表的是匹配就以为是百分百没有任何miss-match,这是不对的,多态性碱基或者单碱基错配也是用M标记&/b&!&/p&&p&&b&第三,MAPQ,比对质量值&/b&&/p&&p&这个值同样非常重要,&b&它告诉我们的是这个read比对到参考序列上这个位置的可靠程度,用错误比对到该位置的概率值(转化为Phred scale)来描述:-10logP{错比概率} 。&/b&因此MAPQ(mapping quality)值大于30就意味着错比概率低于0.001(千分之一),这个值也是我们衡量read比对质量的一个重要因子。&/p&&p&剩下的几列在上面的格式表中描述的也比较清楚,基本没有过于隐藏的信息,因此我就不打算再一一细说了,如果大家依然有困惑可以到后台留言。&/p&&p&此外,细心的同学可能也已经发现了:&b&fastq的所有信息都被涵盖到了BAM文件中了,包括比对不上的read也在,因此获得了BAM其实也等于获得了所有的read&/b&。而且,fastq有时也会被转换成一种uBam文件,指的就是un-mapping BAM——没有做过比对的BAM文件。它相比于Fastq可以用metadata存储更多有用的信息,不过这不是我们这篇文章想说的内容。 &/p&&p&最后,还是再说明一次:BAM文件中除了必须的前11列信息之外,&b&不同的BAM文件中后面记录metadata的列是不固定的,在不同的处理软件中输出时也会有所不同,我们也可以依据实际的情况增删不同的metadata信息&/b&。&/p&&h2&&b&使用samtools view查看BAM文件&/b&&/h2&&p&BAM文件由于是特殊的二进制格式,因此没办法通过文本的形式直接打开,要用samtools的view功能在终端上进行查看(上文也已经说到这里在进行系统补充),如:&/p&&div class=&highlight&&&pre&&code class=&language-bash&&&span&&/span&$ samtools view in.bam
&/code&&/pre&&/div&&p&如果不想从头开始看,希望快速地跳转到基因组的其它位置上,比如chr22染色体,那么可以先用samtools index生成BAM文件的索引(如果已经有索引文件则不需该步骤),然后这样操作:&/p&&div class=&highlight&&&pre&&code class=&language-bash&&&span&&/span&$ samtools index in.bam
&span class=&c1&&# 生成in.bam的索引文件in.bam.bai&/span&
$ samtools view in.bam chr22
&span class=&c1&&# 跳转到chr22染色体&/span&
$ samtools view in.bam chr22:
&span class=&c1&&# 跳转到chr22:位置&/span&
$ samtools view in.bam chr22:50103
&span class=&c1&&# 只查看该位置&/span&
&/code&&/pre&&/div&&h2&&b&IGV或者samtools tview查看比对情况&/b&&/h2&&p&以上,我基本上列举了我们会在终端上如何查看BAM文件的几个最常用操作。但如果你想更直观查看的BAM文件,IGV是目前最好的一个选择,但仅适合于文件还比较小的情况,效果如下:&/p&&figure&&img src=&https://pic3.zhimg.com/v2-1b8be6dd7eededc055a7e_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1120& data-rawheight=&710& class=&origin_image zh-lightbox-thumb& width=&1120& data-original=&https://pic3.zhimg.com/v2-1b8be6dd7eededc055a7e_r.jpg&&&/figure&&p&如果你的BAM文件很大,都超过了你的本地电脑磁盘了,你还是想看该怎么办?你有两个选择:&/p&&p&第一,把你想查看的那部分区域用samtools view提取出来,生成一份小一些的BAM,然后下载下来,在导入到IGV中。&/p&&div class=&highlight&&&pre&&code class=&language-bash&&&span&&/span&$ samtools view -h in.bam chr22:50203 &span class=&p&&|&/span& samtools view -Sb - & small.bam
&/code&&/pre&&/div&&p&第二,不下载,直接在终端用samtools tview进行查看。samtools tview有类似于IGV的功能,虽然体验会稍差一些。&/p&&div class=&highlight&&&pre&&code class=&language-bash&&&span&&/span&$ samtools tview --reference hg38.fa in.bam
&/code&&/pre&&/div&&figure&&img src=&https://pic3.zhimg.com/v2-bd714be424b666aff7ad2_b.jpg& data-size=&normal& data-rawwidth=&1905& data-rawheight=&974& class=&origin_image zh-lightbox-thumb& width=&1905& data-original=&https://pic3.zhimg.com/v2-bd714be424b666aff7ad2_r.jpg&&&figcaption&samtools tview&/figcaption&&/figure&&p&在该模式下,按下键盘‘g’后,会跳出一个Goto框,在里面输入想要调整过去的位置,就行了,比如:&/p&&figure&&img src=&https://pic4.zhimg.com/v2-b5e9bc0dc848a84ee1bc2f_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&595& data-rawheight=&436& class=&origin_image zh-lightbox-thumb& width=&595& data-original=&https://pic4.zhimg.com/v2-b5e9bc0dc848a84ee1bc2f_r.jpg&&&/figure&&p&按下esc键则可以取消。另外,为了节省空间,加快查询效率,read中与参考序列相同的部分被用一串串不同颜色的点表示,只留下miss-match的碱基和发生indel变异的区域。其中圆点表示正链比对,逗号表示负链比对。不同的颜色代表不同的比对质量值:&b&白色&=30,黄色20-29,绿色10-19,蓝色0-9&/b&。如果你还想知道的其他的功能,&b&可以在tview模式里按下“?”问号,就会弹出类似下面这样的帮助窗口,&/b&然后按照指引做就行了。&/p&&figure&&img src=&https://pic3.zhimg.com/v2-6adbb07e8aa0eb83c1cb10a_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&494& data-rawheight=&594& class=&origin_image zh-lightbox-thumb& width=&494& data-original=&https://pic3.zhimg.com/v2-6adbb07e8aa0eb83c1cb10a_r.jpg&&&/figure&&p&虽然看起来不如IGV体验那样好,功能也比较单一(仅可以查看比对情况),但可贵之处在于可以在终端里面直接操作,当需要快速查看某个位置的比对情况时,操作效率非常高。而如果要退出该模式,也非常简单,按下q键就可以了。&/p&&h2&&b&小结&/b&&/h2&&p&那么,有关BAM格式的内容我们就暂且先到这里吧,大家如果有疑惑或者感兴趣的内容都可以到后台留言,我都会定时进行回复。在下一篇文章中,我们将重点介绍如何使用pysam来操作bam文件了。&/p&&hr&&p&本文首发于我的微信公众号:&b&解螺旋的矿工&/b& 欢迎关注更及时了解更多信息。&/p&&figure&&img src=&https://pic1.zhimg.com/v2-a8e2a6badbf09bd3af840_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&479& data-rawheight=&498& class=&origin_image zh-lightbox-thumb& width=&479& data-original=&https://pic1.zhimg.com/v2-a8e2a6badbf09bd3af840_r.jpg&&&/figure&&p&&/p&
经过了第四节的长文,我想大家基本上已经知道了一个WGS流程该如何构建起来了吧。但在那一节中限于篇幅有两个很重要的文件我没能展开来讲,分别是:BAM和VCF文件。这篇我们先说BAM文件。什么是BAMBAM是目前基因数据分析中最通用的比对数据存储格式,它既适合…
&figure&&img src=&https://pic1.zhimg.com/v2-b3a95b97c08ec8bc0647da_b.jpg& data-rawwidth=&1438& data-rawheight=&809& class=&origin_image zh-lightbox-thumb& width=&1438& data-original=&https://pic1.zhimg.com/v2-b3a95b97c08ec8bc0647da_r.jpg&&&/figure&&p&这是本系列中最重要的一篇文章。但在开始之前,我想先说一句:&b&流程的具体形式其实是次要的,WGS本质上只是一个技术手段,重要的是,我们要明白自己所要解决的问题是什么,所希望获取的结果是什么,然后再选择合适的技术。&/b&这是许多人经常忽视的一个重要问题。&/p&&p&&br&&/p&&p&好了,以下进入正文。&/p&&figure&&img src=&https://pic4.zhimg.com/v2-7efc9eba85b2de3fd325b099f8051d74_b.jpg& data-size=&normal& data-rawwidth=&1716& data-rawheight=&493& class=&origin_image zh-lightbox-thumb& width=&1716& data-original=&https://pic4.zhimg.com/v2-7efc9eba85b2de3fd325b099f8051d74_r.jpg&&&figcaption&主流程&/figcaption&&/figure&&p&这是WGS数据分析的流程图。流程的目的是准确检测出每个样本(这里特指人)基因组中的变异集合,也就是人与人之间存在差异的那些DNA序列。我把整个分析过程按照它们实际要完成的功能,将其分成了三个大的模块:&/p&&ol&&li&原始数据质控&/li&&li&数据预处理&/li&&li&变异检测&/li&&/ol&&p&这或许和很多人看到的WGS分析流程,在结构梳理上有些差异(比如GATK的最佳实践),但过程中的各个步骤和所要完成的事情是一模一样的。&/p&&p&&br&&/p&&h2&&b&0.准备阶段&/b&&/h2&&p&在开始之前,我们需要做一些准备工作,主要是部署好相关的软件和工具。我们在这个WGS数据分析过程中用到的所有软件都是开源的,它们的代码全部都能够在github上找到,具体如下:&/p&&ul&&li&&a href=&https://link.zhihu.com/?target=https%3A//github.com/lh3/bwa& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&BWA(Burrow-Wheeler Aligner)&/a&:
这是最权威,使用最广的NGS数据比对软件,目前已经更新到0.7.16版本;&/li&&li&&a href=&https://link.zhihu.com/?target=https%3A//github.com/samtools/samtools& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Samtools&/a&:是一个专门用于处理比对数据的工具,由BWA的作者(lh3)所编写;&/li&&li&&a href=&https://link.zhihu.com/?target=http%3A//broadinstitute.github.io/picard/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Picard&/a&:它是目前最著名的组学研究中心-Broad研究所开发的一款强大的NGS数据处理工具,功能方面和Samtools有些重叠,但更多的是互补,它是由java编写的,我们直接下载最新的.jar包就行了。&/li&&li&&a href=&https://link.zhihu.com/?target=https%3A//software.broadinstitute.org/gatk/download/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&GATK&/a&:同样是Broad研究所开发的,是目前业内最权威、使用最广的基因数据变异检测工具。值得注意的是,目前GATK有3.x和4.x两个不同的版本,代码在github上也是分开的。4.x是今年新推出的,在核心算法层面并没太多的修改,但使用了新的设计模式,做了很多功能的整合,是更适合于大规模集群和云运算的版本,后续GATK团队也将主要维护4.x的版本,而且它的代码是100%开源的,这和3.x只有部分开源的情况不同。看得出GATK今年的这次升级是为了应对接下来越来越多的大规模人群测序数据而做出的改变,但现阶段4.x版本还不稳定,真正在使用的人和机构其实也还不多。短期来看,3.x版本还将在业内继续使用一段时间;其次,3.x对于绝大分部的分析需求来说是完全足够的。我们在这里也以GATK3.8(最新版本)作为流程的重要工具进行分析流程的构建。&/li&&/ul&&p&同时,对于构造WGS分析流程来说,以上这个四个工具就完全足够了。它们的安装都非常简单,除了BWA和Samtools由C编写的,安装时需要进行编译之外,另外两个只要保证系统中的java是1.8.x版本及以上的,那么直接下载jar包就可以使用了。操作系统方面推荐linux(集群)或者Mac OS。&/p&&p&&br&&/p&&h2&&b&1.原始数据质控&/b&&/h2&&p&数据的质控,由于我已经在&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&上一节&/a&的文章中讲的比较详细了,因此在本篇中就不再进行详细的讨论了。而且质控的处理方法都是比较一致的,基本不需要为特定的分析做定制化的改动,因此,我们可以把它作为WGS主流程之外的一环。但还是再强调一下,数据质控的地位同样重要,不然我也不必专门为其单独写一篇完整的文章。&/p&&p&&br&&/p&&h2&&b&2.数据预处理&/b&&/h2&&p&&b&序列比对&/b&&/p&&p&先问一个问题:为什么需要比对?&/p&&p&我们已经知道NGS测序下来的短序列(read)存储于FASTQ文件里面。虽然它们原本都来自于有序的基因组,但在经过DNA建库和测序之后,文件中不同read之间的前后顺序关系就已经全部丢失了。因此,FASTQ文件中紧挨着的两条read之间没有任何位置关系,它们都是随机来自于原本基因组中某个位置的短序列而已。&/p&&p&因此,我们需要先把这一大堆的短序列捋顺,一个个去跟该物种的&b&参考基因组&/b&比较,找到每一条read在参考基因组上的位置,然后按顺序排列好,这个过程就称为&b&测序数据的比对&/b&。这也是&b&核心流程真正意义上的第一步&/b&,只有完成了这个序列比对我们才有下一步的数据分析。&/p&&blockquote&【注】参考基因组:指该物种的基因组序列,是已经组装成的完整基因组序列,常作为该物种的标准参照物,比如人类基因组参考序列,fasta格式。&/blockquote&&p&序列比对本质上是一个寻找最大公共子字符串的过程。大家如果有学过生物信息学的话,应该或多或少知道BLAST,它使用的是动态规划的算法来寻找这样的子串,但在面对巨量的短序列数据时,类似BLAST这样的软件实在太慢了!因此,需要更加有效的数据结构和相应的算法来完成这个搜索定位的任务。&/p&&p&我们这里将用于流程构建的BWA就是其中最优秀的一个,它将BW(Burrows-Wheeler)压缩算法和后缀树相结合,能够让我们以较小的时间和空间代价,获得准确的序列比对结果。&/p&&p&&br&&/p&&p&以下我们就开始流程的搭建。&/p&&p&首先,我们需要为参考基因组的构建索引——这其实是在为参考序列进行Burrows Wheeler变换(wiki: 块排序压缩),以便能够在序列比对的时候进行快速的搜索和定位。&/p&&div class=&highlight&&&pre&&code class=&language-bash&&&span&&/span&$ bwa index human.fasta
&/code&&/pre&&/div&&p&以我们人类的参考基因组(3Gb长度)为例,这个构造过程需要消耗几个小时的时间(一般3个小时左右)。完成之后,你会看到类似如下几个以human.fasta为前缀的文件:&/p&&div class=&highlight&&&pre&&code class=&language-bash&&&span&&/span&.
├── human.fasta.amb
├── human.fasta.ann
├── human.fasta.bwt
├── human.fasta.pac
└── human.fasta.sa
&/code&&/pre&&/div&&p&这些就是在比对时真正需要被用到的文件。这一步完成之后,我们就可以将read比对至参考基因组了:&/p&&div class=&highlight&&&pre&&code class=&language-bash&&&span&&/span&$ bwa mem -t &span class=&m&&4&/span& -R &span class=&s1&&'@RG\tID:foo_lane\tPL:illumina\tLB:library\tSM:sample_name'&/span& /path/to/human.fasta read_1.fq.gz read_2.fq.gz & sample_name.sam
&/code&&/pre&&/div&&p&大伙如果以前没使用过这个比对工具的话,那么可能不明白上面参数的含义。我们这里调用的是bwa的mem比对模块,在解释这样做之前,我们先看一下bwa mem的&b&官方用法&/b&说明,它就一句话:&/p&&div class=&highlight&&&pre&&code class=&language-bash&&&span&&/span&Usage: bwa mem &span class=&o&&[&/span&options&span class=&o&&]&/span& &idxbase& &in1.fq& &span class=&o&&[&/span&in2.fq&span class=&o&&]&/span&
&/code&&/pre&&/div&&p&其中,[options]是一系列可选的参数,暂时不多说。这里的 &idxbase& 要输入的是参考基因组的BW索引文件,我们上面通过bwa index构建好的那几个以human.fasta为前缀的文件便是;&in1.fq&和[in2.fq]输入的是质控后的fastq文件。但这里输入的时候为什么会需要两个fq(in1.fq和in2.fq)呢?我们上面的例子也是有两个:read_1.fq.gz和read_2.fq.gz。这是因为这是&b&双末端测序(也称Pair-End)&/b&的情况,那什么是“双末端测序”呢?这两个fq之间的关系又是什么?这个我需要简单解析一下。&/p&&p&我们已经知道NGS是短读长的测序技术,一次测出来的read的长度都不会太长,那为了尽可能把一个DNA序列片段&b&尽可能多地测出来&/b&,既然测一边不够,那就测两边,于是就有了一种从被测DNA序列两端各测序一次的模式,&b&这就被称为双末端测序(Pair-End Sequencing,简称PE测序)&/b&。如下图是Pair-End测序的示意图,中间灰色的是被测序的DNA序列片段,左边黄色带箭头和右边蓝色带箭头的分别是测序出来的read1和read2序列,这里假定它们的长度都是100bp。虽然很多时候Pair-End测序还是无法将整个被测的DNA片段完全测通,但是它依然提供了极其有用的信息,比如,我们知道每一对的read1和read2都来自于同一个DNA片段,read1和read2之间的距离是这个DNA片段的长度,而且read1和read2的方向刚好是相反的(这里排除mate-pair的情形)等,这些信息对于后面的变异检测等分析来说都是非常有用的。&/p&&figure&&img src=&https://pic1.zhimg.com/v2-6cdca972b572daf83e17_b.jpg& data-size=&normal& data-rawwidth=&457& data-rawheight=&282& class=&origin_image zh-lightbox-thumb& width=&457& data-original=&https://pic1.zhimg.com/v2-6cdca972b572daf83e17_r.jpg&&&figcaption&Pair-End 测序&/figcaption&&/figure&&p&另外,在read1在fq1文件中位置和read2在fq2文件中的文件中的位置是相同的,而且read ID之间只在末尾有一个'/1'或者'/2'的差别。&/p&&figure&&img src=&https://pic1.zhimg.com/v2-140b6b8abe28bb61eb0acb_b.jpg& data-size=&normal& data-rawwidth=&995& data-rawheight=&552& class=&origin_image zh-lightbox-thumb& width=&995& data-original=&https://pic1.zhimg.com/v2-140b6b8abe28bb61eb0acb_r.jpg&&&figcaption&read1 ID和read2 ID的差别&/figcaption&&/figure&&p&既然有双末端测序,那么与之对应的就有单末端测序(Single End Sequecing,简称SE测序),即只测序其中一端。因此,我们在使用bwa比对的时候,实际上,in2.fq是非强制性的(所以用方括号括起来),只有是双末端测序的数据时才需要添加。&/p&&p&回到上面我们的例子,大伙可以看到我这里除了用法中提到的参数之外,还多了2个额外的参数,分别是:-t,线程数,我们在这里使用4个线程;-R 接的是&b&Read Group的字符串信息&/b&,这&b&是一个非常重要的信息&/b&,以@RG开头,它是用来将比对的read进行分组的。不同的组之间测序过程被认为是相互独立的,这个信息对于我们后续对比对数据进行错误率分析和Mark duplicate时非常重要。在Read Group中,有如下几个信息非常重要:&/p&&p&1) ID,这是Read Group的分组ID,一般设置为测序的lane ID(不同lane之间的测序过程认为是独立的),下机数据中我们都能看到这个信息的,一般都是包含在fastq的文件名中;&/p&&p&2) PL,指的是所用的测序平台,&b&这个信息不要随便写!&/b&特别是当我们需要使用GATK进行后续分析的时候,更是如此!这是一个很多新手都容易忽视的一个地方,在GATK中,PL只允许被设置为:ILLUMINA,SLX,SOLEXA,SOLID,454,LS454,COMPLETE,PACBIO,IONTORRENT,CAPILLARY,HELICOS或UNKNOWN这几个信息。基本上就是目前市场上存在着的测序平台,当然,如果实在不知道,那么必须设置为UNKNOWN,名字方面不区分大小写。如果你在分析的时候这里没设置正确,那么在后续使用GATK过程中&b&可能会碰到类似如下的错误&/b&:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&ERROR MESSAGE: The platform (xx) associated with read group GATKSAMReadGroupRecord @RG:xx is not a recognized platform.
&/code&&/pre&&/div&&p&这个时候你需要对比对文件的header信息进行重写,就会稍微比较麻烦。&/p&&p&我们上面的例子用的是PL:illumina。如果你的数据是CG测序的那么记得不要写成CG!而要写COMPLETE。&/p&&p&3) SM,样本ID,同样非常重要,有时候我们测序的数据比较多的时候,那么可能会分成多个不同的lane分布测出来,这个时候SM名字就是可以用于区分这些样本;&/p&&p&4) LB,测序文库的名字,这个重要性稍微低一些,主要也是为了协助区分不同的group而存在。文库名字一般可以在下机的fq文件名中找到,如果上面的lane ID足够用于区分的话,也可以不用设置LB;&/p&&p&除了以上这四个之外,还可以自定义添加其他的信息,不过如无特殊的需要,对于序列比对而言,这4个就足够了。这些信息设置好之后,在&b&RG字符串中要用制表符(\t)将它们分开&/b&。&/p&&p&最后在我们的例子中,我们将比对的输出结果直接重定向到一份sample_name.sam文件中,这类文件是BWA比对的标准输出文件,它的具体格式我会在下一篇文章中进行详细说明。但SAM文件是文本文件,一般整个文件都非常巨大,因此,为了有效节省磁盘空间,一般都会用samtools将它转化为BAM文件(SAM的特殊二进制格式),而且BAM会更加方便于后续的分析。所以我们上面比对的命令可以和samtools结合并改进为:&/p&&div class=&highlight&&&pre&&code class=&language-bash&&&span&&/span&$ bwa mem -t &span class=&m&&4&/span& -R &span class=&s1&&'@RG\tID:foo_lane\tPL:illumina\tLB:library\tSM:sample_name'&/span& /path/to/human.fasta read_1.fq.gz read_2.fq.gz &span class=&p&&|&/span& samtools view -S -b - & sample_name.bam
&/code&&/pre&&/div&&p&我们通过管道(“|”)把比对的输出如同引导水流一样导流给samtools去处理,上面samtools view的-b参数指的就是输出为BAM文件,这里需要注意的地方是-b后面的 '-',它代表就是上面管道引流过来的数据,经过samtools转换之后我们再重定向为sample_name.bam。&/p&&p&关于BWA的其他参数,我这里不打算对其进行一一解释,在绝大多数情况下,采用默认是合适的做法。&/p&&blockquote&[Tips] BWA MEM比对模块是有一定适用范围的:它是专门为长read比对设计的,目的是为了解决,第三代测序技术这种能够产生长达几十kb甚至几Mbp的read情况。一般只有当read长度≥70bp的时候,才推荐使用,如果比这个要小,建议使用BWA ALN模块。&/blockquote&&p&&br&&/p&&p&&b&排序&/b&&/p&&p&以上,我们就完成了read比对的步骤。接下来是排序:&/p&&figure&&img src=&https://pic4.zhimg.com/v2-3ea8c7dab7b7e5b9a7c3a2d_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&940& data-rawheight=&641& class=&origin_image zh-lightbox-thumb& width=&940& data-original=&https://pic4.zhimg.com/v2-3ea8c7dab7b7e5b9a7c3a2d_r.jpg&&&/figure&&p&排序这一步我们也是通过使用samtools来完成的,命令很简单:&/p&&div class=&highlight&&&pre&&code class=&language-bash&&&span&&/span&Usage: samtools sort &span class=&o&&[&/span&options...&span class=&o&&]&/span& &span class=&o&&[&/span&in.bam&span class=&o&&]&/span&
&/code&&/pre&&/div&&p&但在执行之前,我们有必要先搞明白为什么需要排序,为什么BWA比对后输出的BAM文件是没顺序的!原因就是FASTQ文件里面这些被测序下来的read是随机分布于基因组上面的,第一步的比对是按照FASTQ文件的顺序把read逐一定位到参考基因组上之后,随即就输出了,它不会也不可能在这一步里面能够自动识别比对位置的先后位置重排比对结果。因此,比对后得到的结果文件中,每一条记录之间位置的先后顺序是乱的,我们后续去重复等步骤都需要在比对记录按照顺序从小到大排序下来才能进行,所以这才是需要进行排序的原因。对于我们的例子来说,这个排序的命令如下:&/p&&div class=&highlight&&&pre&&code class=&language-bash&&&span&&/span&$ &span class=&nb&&time&/span& samtools sort -@ &span class=&m&&4&/span& -m 4G -O bam -o sample_name.sorted.bam sample_name.bam
&/code&&/pre&&/div&&p&其中,-@,用于设定排序时的线程数,我们设为4;-m,限制排序时最大的内存消耗,这里设为4GB;-O 指定输出为bam格式;-o 是输出文件的名字,这里叫sample_name.sorted.bam。我会比较建议大伙在做类似分析的时候在文件名字将所做的关键操作包含进去,因为这样即使过了很长时间,当你再去看这个文件的时候也能够立刻知道当时对它做了什么;最后就是输入文件——sample_name.bam。&/p&&blockquote&【注意】排序后如果发现新的BAM文件比原来的BAM文件稍微小一些,不用觉得惊讶,这是压缩算法导致的结果,文件内容是没有损失的。&/blockquote&&p&&br&&/p&&p&&b&去除重复序列(或者标记重复序列)&/b&&/p&&figure&&img src=&https://pic1.zhimg.com/v2-74c97e0c6fd0b6c6b3aba6bd4bffaf3d_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&942& data-rawheight=&638& class=&origin_image zh-lightbox-thumb& width=&942& data-original=&https://pic1.zhimg.com/v2-74c97e0c6fd0b6c6b3aba6bd4bffaf3d_r.jpg&&&/figure&&p&&br&&/p&&p&在排序完成之后我们就可以开始执行去除重复(准确来说是&b&去除PCR重复序列&/b&)的步骤了。&/p&&p&首先,我们需要先理解什么是重复序列,它是如何产生的,以及为什么需要去除掉?要回答这几个问题,我们需要再次理解在建库和测序时到底发生了什么。&/p&&p&我们在&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&第一节&/a&中已经知道,在NGS测序之前都需要先构建测序文库:通过物理(超声)打断或者化学试剂(酶切)切断原始的DNA序列,然后选择特定长度范围的序列去进行PCR扩增并上机测序。&/p&&p&因此,这里重复序列的来源实际上就是由PCR过程中所引入的。因为所谓的PCR扩增就是把原来的一段DNA序列复制多次。可是为什么需要PCR扩增呢?如果没有扩增不就可以省略这一步了吗?&/p&&p&情况确实如此,但是很多时候我们构建测序文库时能用的细胞量并不会非常充足,而且在打断的步骤中也会引起部分DNA的降解,这两点会使&b&整体&/b&或者&b&局部的DNA浓度过低&/b&,这时如果直接从这个溶液中取样去测序就很可能漏掉原本基因组上的一些DNA片段,&b&导致测序不全&/b&。而PCR扩增的作用就是为了把这些微弱的DNA多复制几倍乃至几十倍,以便增大它们在溶液中分布的密度,使得能够在取样时被获取到。所以这里大家需要记住一个重点,PCR扩增原本的目的是为了增大微弱DNA序列片段的密度,但由于整个反应都在一个试管中进行,因此其他一些密度并不低的DNA片段也会被同步放大,那么这时在取样去上机测序的时候,这些DNA片段就很可能会被重复取到相同的几条去进行测序(下图为PCR扩增示意图)。&/p&&figure&&img src=&https://pic1.zhimg.com/v2-d01a2a48deac2e3b6f5f02_b.jpg& data-size=&normal& data-rawwidth=&1200& data-rawheight=&1162& class=&origin_image zh-lightbox-thumb& width=&1200& data-original=&https://pic1.zhimg.com/v2-d01a2a48deac2e3b6f5f02_r.jpg&&&figcaption&PCR扩增示意图:PCR扩增是一个指数扩增的过程,图中原本只有一段双链DNA序列,在经过3轮PCR后就被扩增成了8段&/figcaption&&/figure&&p&看到这里,你或许会觉得,那没必要去除不也应该可以吗?因为即便扩增了多几次,不也同样还是原来的那一段DNA吗?直接用来分析对结果也不会有影响啊!难道不是吗?&/p&&p&&b&会有影响,而且有时影响会很大!&/b&最直接的后果就是同时增大了变异检测结果的假阴和假阳率。主要有几个原因:&/p&&ol&&li&&b&DNA在打断的那一步会发生一些损失,主要表现是会引发一些碱基发生颠换变换(嘌呤-变嘧啶或者嘧啶变嘌呤),带来假的变异。PCR过程会扩大这个信号,导致最后的检测结果中混入了假的结果;&/b&&/li&&li&&b&PCR反应过程中也会带来新的碱基错误。发生在前几轮的PCR扩增发生的错误会在后续的PCR过程中扩大,同样带来假的变异;&/b&&/li&&li&&b&对于真实的变异,PCR反应可能会对包含某一个碱基的DNA模版扩增更加剧烈(这个现象称为PCR Bias)。因此,如果反应体系是对含有reference allele的模板扩增偏向强烈,那么变异碱基的信息会变小,从而会导致假阴&/b&。&/li&&/ol&&p&&b&PCR对真实的变异检测和个体的基因型判断都有不好的影响&/b&。GATK、Samtools、Platpus等这种利用贝叶斯原理的变异检测算法都是认为所用的序列数据都不是重复序列(&b&即将它们和其他序列一视同仁地进行变异的判断,所以带来误导&/b&),因此必须要进行标记(去除)或者使用PCR-Free的测序方案(这个方案目前正变得越来越流行,特别是对于RNA-Seq来说尤为重要,现在著名的基因组学研究所——Broad Institute,基本都是使用PCR-Free的测序方案)。&/p&&p&那么具体是如何做到去除这些PCR重复序列的呢?我们可以抛开任何工具,仔细想想,既然PCR扩增是把同一段DNA序列复制出很多份,那么这些序列在经过比对之后它们一定会定位到基因组上相同的位置,比对的信息看起来也将是一样的!于是,我们就可以根据这个特点找到这些重复序列了!&/p&&figure&&img src=&https://pic2.zhimg.com/v2-1e4d1631dbad5b7dc02f93_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&819& data-rawheight=&437& class=&origin_image zh-lightbox-thumb& width=&819& data-original=&https://pic2.zhimg.com/v2-1e4d1631dbad5b7dc02f93_r.jpg&&&/figure&&p&事实上,现有的工具包括Samtools和Picard中去除重复序列的算法也的确是这么做的。不同的地方在于,samtools的rmdup是直接将这些重复序列从比对BAM文件中删除掉,而Picard的MarkDuplicates默认情况则只是在BAM的FLAG信息中标记出来,而不是删除,因此这些重复序列依然会被留在文件中,只是我们可以在变异检测的时候识别到它们,并进行忽略。&/p&&p&考虑到尽可能和现在主流的做法一致(但我并不是说主流的做法就一定是对的,要分情况看待,只是主流的做法容易被做成生产流程而已),我们这里也用Picard来完成这个事情:&/p&&div class=&highlight&&&pre&&code class=&language-bash&&&span&&/span&java -jar picard.jar MarkDuplicates &span class=&se&&\ &/span&
&span class=&nv&&I&/span&&span class=&o&&=&/span&sample_name.sorted.bam &span class=&se&&\&/span&
&span class=&nv&&O&/span&&span class=&o&&=&/span&sample_name.sorted.markdup.bam &span class=&se&&\&/span&
&span class=&nv&&M&/span&&span class=&o&&=&/span&sample_name.markdup_metrics.txt
&/code&&/pre&&/div&&p&这里只把重复序列在输出的新结果中标记出来,但不删除。如果我们非要把这些序列完全删除的话可以这样做:&/p&&div class=&highlight&&&pre&&code class=&language-bash&&&span&&/span&java -jar picard.jar MarkDuplicates &span class=&se&&\ &/span&
&span class=&nv&&REMOVE_DUPLICATES&/span&&span class=&o&&=&/span&&span class=&nb&&true&/span& &span class=&se&&\&/span&
&span class=&nv&&I&/span&&span class=&o&&=&/span&sample_name.sorted.bam &span class=&se&&\&/span&
&span class=&nv&&O&/span&&span class=&o&&=&/span&sample_name.sorted.markdup.bam &span class=&se&&\&/span&
&span class=&nv&&M&/span&&span class=&o&&=&/span&sample_name.markdup_metrics.txt
&/code&&/pre&&/div&&p&把参数REMOVE_DUPLICATES设置为ture,那么重复序列就被删除掉,不会在结果文件中留存。我比较建议使用第一种做法,只是标记出来,并留存这些序列,以便在你需要的时候还可以对其做分析。&/p&&p&这一步完成之后,我们需要为sample_name.sorted.markdup.bam创建索引文件,它的作用能够让我们可以随机访问这个文件中的任意位置,而且后面的“局部重比对”步骤也要求这个BAM文件一定要有索引,命令如下:&/p&&div class=&highlight&&&pre&&code class=&language-bash&&&span&&/span&$ samtools index sample_name.sorted.markdup.bam
&/code&&/pre&&/div&&p&完成之后,会生成一份sample_name.sorted.markdup.bam.bai文件,这就是上面这份B}

我要回帖

更多关于 举个例子 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信