普通视图

发现新文章,点击刷新页面。
昨天以前郑泽鑫的博客

使用 Github Actions 自动更新 ANNOVAR 的 Clinvar 数据库

2021年6月15日 06:20

前段时间,看到ANNOVAR在文档里更新了一个可以自行更新Clinvar数据库的脚本,ANNOVAR更新Clinvar的频率,一般是半年到一年才更新一次。

ANNOVAR文档

恰好又看到Github新推出了“Flat Data”,就想着是不是能够像Flat Data一样,抓取Clinvar数据库,然后定期更新成ANNOVAR数据库;可惜研究了一圈,Flat Data的示例都是使用JavaScript或者Typescript脚本的。 ​ 此路不通,那就换一条路,使用David Baux的脚本和Github Actions来实现以下目的: ​

  1. 定时从NCBI抓取Clinvar的VCF更新(Github在国外,下载快);
  2. 转换成ANNOVAR的数据库文件(省却下载到服务器再处理的步骤);
  3. 发布到Github repo和打包成release,使用CDN加速下载

正好Clinvar的数据库压缩后的文件为15Mb左右,不会超过大小限制;其他ANNOVAR的数据库,也可以使用相同的实现方法。

建立Github repo

首先我们建立一个repo,如ryuzheng/clinvar_db_for_annovar,主要存放生成的Clinvar数据库文件、release和Github Actions脚本; ​ 然后为了整洁,我另外建立2个repo,分别存放

  1. 需要用到的ANNOVAR脚本,如ryuzheng/ANNOVAR_script,版权问题,设置为私有repo,请自行到ANNOVAR官网下载
    • convert2annovar.pl
    • index_annovar.pl
  2. 修改过的脚本,如ryuzheng/update_annovar_db,修改为下载weekly更新的VCF与其他一些更适合Github Actions的改动,这里不赘述

然后我们通过submodule,将这2个repo与原来的主repo连接起来,

# 进入主repo的文件夹
cd clinvar_db_for_annovar

# 注意这个repo是私有的,所以得用ssh的形式
git submodule add git@github.com:ryuzheng/ANNOVAR_script.git

# 这个repo是公开的,https和ssh的形式都可以
git submodule add https://github.com/ryuzheng/update_annovar_db.git、

# 后期如果更新了其中某个submodule的repo,需要更新链接的版本
git submodule update --remote
# 或者进入submodule的文件夹
cd update_annovar_db
git pull origin main

我们整个目录的结构如图

目录结构

这样做的好处是,

  • 主repo看起来很干净,只存放生成的文件,并且commit的记录也很干净;
  • 后期如果需要更新代码,我们只需要单独修改submodule的链接,submodule项目的其他代码修改不会影响这个项目;
  • 由于部分代码不能公开,submodule可以引入私有repo

编写Github Actions

我们在repo文件夹下建立.github/workflows文件夹,用来存放Github Actions的yml文件,Github会自动识别该文件夹下的yml文件。 ​ 在.github/workflows下新建一个update_clinvar.yml文件,内容如下:

name: Update Clinvar database for ANNOVAR # 设置该action的名称

on:
  schedule:
    - cron: "0 0 */3 * *" # 由于Clinvar一周更新一次,这里设置为每3天一次
  workflow_dispatch: # 用于手动执行

然后我们先建立第一个任务(jobs),将这个任务命名为build,运行我们修改后脚本,将clinvar的VCF文件转换成ANNOVAR的数据库,并上传结果到artifacts,用于下一步。

jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        genome: ["hg19", "hg38"] # 设置一个matrix,分别为hg19和hg38 2个基因组版本的任务

    steps:
      - uses: actions/checkout@v2
        with:
          token: ${{ secrets.GH_TOKEN }}
          submodules: "true"

      - name: Set up Python 3.9 # 使用python 3
        uses: actions/setup-python@v1
        with:
          python-version: 3.9

      - name: Install dependencies # 安装依赖
        run: |
          python -m pip install --upgrade pip
          pip install -r requirement.txt

      - name: Update Clinvar with GRCh37 # hg19的clinvar文件处理
        if: matrix.genome == 'hg19'
        run: |
          cd ./update_annovar_db
          python3 ./update_resources.py -d clinvar -w -hp ../Clinvar_build/hg19 -a ../ANNOVAR_script -g GRCh37

      - name: Update Clinvar with GRCh38 # hg38的clinvar文件处理
        if: matrix.genome == 'hg38'
        run: |
          cd ./update_annovar_db
          python3 ./update_resources.py -d clinvar -w -hp ../Clinvar_build/hg38 -a ../ANNOVAR_script -g GRCh38

      - name: Upload artifacts # 上一步生成地址为Clinvar_build/hg*,上传文件成artifact
        uses: actions/upload-artifact@v2
        with:
          name: ${{ matrix.genome }}
          path: ./Clinvar_build/${{ matrix.genome }}

然后我们建立第二个任务,将这个任务命名为release,用于当clinvar更新时,存放我们更新后的文件,以及打包成release发布。

  release:
    runs-on: ubuntu-latest
    needs: build # 需要上一步build执行成功后方能执行

    steps:
      - uses: actions/checkout@v2
        with:
          token: ${{ secrets.GH_TOKEN }}

      - name: clean previous build # 删除之前的版本
        run: |
          rm -f Clinvar_build/hg19/*
          rm -f Clinvar_build/hg38/*

      - name: Download artifacts for GRCh37 # 将hg19的artifact下载到指定路径
        uses: actions/download-artifact@v2
        with:
          name: "hg19"
          path: ./Clinvar_build/hg19

      - name: Download artifacts for GRCh38 # 将hg38的artifact下载到指定路径
        uses: actions/download-artifact@v2
        with:
          name: "hg38"
          path: ./Clinvar_build/hg38

      - name: Commit # 只有文件发生变动,才会commit
        id: auto-commit-action
        uses: stefanzweifel/git-auto-commit-action@v4

      - name: Push changes
        uses: ad-m/github-push-action@master
        with:
          github_token: ${{ secrets.GH_TOKEN }}
          branch: master

      - name: Get current date # 获取当前日期,作为release的版本
        id: date
        run: echo "::set-output name=date::$(date +'%Y-%m-%d')"

      - name: Create Github Release # 只有新的commit,才打包发布新版本
        if: steps.auto-commit-action.outputs.changes_detected == 'true'
        uses: actions/create-release@v1
        id: create_release
        with:
          tag_name: tag-${{ steps.date.outputs.date }}
          release_name: release-${{ steps.date.outputs.date }}
        env:
          GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}

      - name: Upload assets to Github Release # 将生成文件上传到release的asset
        if: steps.auto-commit-action.outputs.changes_detected == 'true'
        uses: csexton/release-asset-action@v2
        with:
          pattern: "Clinvar_build/*/*.gz"
          github-token: ${{ secrets.GH_TOKEN }}
          release-url: ${{ steps.create_release.outputs.upload_url }}

完整的yml文件请查看update_clinvar.yml。 ​

配置Github token

​ 在上一步的yml文件里,相信大家多次看到类似github_token: ${{ secrets.GH_TOKEN }}这样的配置,这是因为Github在执行诸如commit、checkout、push等git操作时,都需要权限,因此我们需要配置一个token。而这个token,我们放在secrets里,别人是无法看到的。

打开Personal access tokens,点击右上角的Generate new token,输入一个名字用于识别,然后勾选上repo的框(允许repo的操作,视乎你所需的权限),然后点击Generate token,将生成的token复制好。

Generate new token

再打开你的repo的Settings选项卡,然后选择Secrets该项,点击右上角的New repository secret,填入名称,如GH_TOKEN,这个名称要与yml里的${{ secrets.GH_TOKEN }}相同,然后将刚才复制好的token填入下面的value里。

repository secret

这样我们就配置好了token;如果大家有其他密钥或者需要保密的内容,也可以设置在secrets里。 ​

运行Github Actions

我们点击repo的Actions选项卡进入该repo的Actions,第一次进去,可能会提示Get started with GitHub Actions,我们点击“Skip this and set up a workflow yourself”就行。 ​ 然后我们在All workflows下会看到我们刚才命名为Update Clinvar database for ANNOVAR的action,点击进入,点击右边的run workflow就可以手动执行。

run workflow

如果执行成功,我们可以看到不同的jobs运行结果以及生成的artifacts。

运行结果

CDN加速下载

打开https://github.com/ryuzheng/clinvar_db_for_annovar/releases/latest,就能看到最新的release,我们可以FastGit或者jsDelivr来作为CDN,示例如下

# Release
# 假设下载链接为https://github.com/ryuzheng/clinvar_db_for_annovar/releases/download/tag-2021-05-21/hg19_clinvar_20210517.txt.gz
wget https://download.fastgit.org/ryuzheng/clinvar_db_for_annovar/releases/download/tag-2021-05-21/hg19_clinvar_20210517.txt.gz

# 假设文件位置为Clinvar_build/hg38/hg38_clinvar_20210517.txt.gz
wget https://cdn.jsdelivr.net/gh/ryuzheng/clinvar_db_for_annovar/Clinvar_build/hg38/hg38_clinvar_20210517.txt.gz

至此,我们的目的已经达成,如无意外,Github Actions会每3天去抓取Clinvar最新的VCF文件,并转换成ANNOVAR的文件形式。 ​

一个小讨论

ANNOVAR在进行VCF注释之前,需要先对VCF文件进行split以及left-normalization(详见VCF Processing Guide),因为ANNOVAR的注释文件,都是left-normalization的。

VCF文件处理

那么Clinvar的VCF文件,是否需要进行split和left-normalization,然后再转换成ANNOVAR的注释文件?这个问题David Baux也提到了

David Baux

我对Clinvar的VCF文件进行了测试,发现它已经是split和left-normalization的了。由此验证了我以前看过某篇博客,上面说Clinvar的突变描述格式,在基因组注释,是left-normalization,而在cDNA注释和氨基酸注释上,则遵循HGVS的标准。这或许能作为我们处理突变描述格式时的一个参考。 ​ 截止该篇博客发布,这个repo已经运行了将近一个月,目前已经较为稳定,欢迎大家使用。

2020 年终总结

2021年1月1日 00:00

图 1. 南都的记疫

与上述信息同样高度契合的,是微信公号 “小山狗” 1 月 28 日曾发布过的一篇题为 “记录一下首次发现新型冠状病毒的经历” 的文章。作者在留言区自称就职于位于广州黄埔的一家民营企业,文中记录:“2019 年 12 月 26 日刚上班,还是如往常一样先大概浏览一下这一天的 mNGS 病原微生物自动解读结果。意外的是,发现有一个样本报出了敏感病原体 ——SARS 冠状病毒,有几十条的序列,且这个样本只有这么一个有意义的病原体。心头一紧,赶紧后台查看详细的分析数据,发现相似度并不算很高,只有大约 94.5%。为了确认结果的可靠性,开始了详细分析。探索版的分析结果提示这个病原体跟 Bat SARS like coronavirus(蝙蝠类 SARS 冠状病毒)最相似,整体相似度在 87% 左右,而跟 SARS 的相似度是约 81%。”

——《财新 | 独家 | 新冠病毒基因测序溯源:警报是何时拉响的》

今年年初时小山狗的那篇文章在群里转发开来,一方面,我惊讶于他们的速度(24日收到样品,27日口头报告新冠病毒,而到了30日,已经有3家公司报告了这个病毒);另一方面,我对于自己工作于生物这个行业而感到荣幸,虽不如这些大佬那么牛逼,但是无论是从事肿瘤药物检测、遗传病,还是病原体检测等,生物行业对群众都是有用的,而且生物行业的成熟,检测到病毒,短时间内就组装好了病毒序列,分享给全世界(参考科技爱好者周刊(第 139 期):生物学的可怕进展这一期的本周话题),以及后来的检测试剂盒开发,我认为在这一次疫情中,生物行业的反应速度和表现,可以说满分不为过。

工作

有一个之前听说过的故事,最近又听了一次,对我有些触动:

有一个人问一个得道的老和尚:“得道前干啥?”老和尚说:“挑水、扫地、做饭。”这个人又问得道后呢。回答依然是挑水、扫地、做饭。那人又问区别在哪里。老和尚回答说:“不得道前挑水时想着扫地,扫地时想着做饭。现在挑水时想着挑水,扫地时想着扫地,做饭时想着做饭。”

有时候我们工作久了,想达到的目标就多,所以我们工作时就会做着这件事情时就想着下一件,比如做着RNA分析时,就想着要是我去学机器学习,将一些机器学习的方法应用到分析中,是不是能达到更好的效果。

而且我们做生信分析时,有时候就是要等程序运行完,才能得到结果,而等结果这段时间,又想着给自己安排一些其他工作,结果边做着其他工作,边时不时看看程序跑完没有,最后就是三心两意。

所以工作越久,越觉得自己专注力不行,效率下降。看到这个故事之后,我忽然明白,心里装的事情越多,越不可能把当前的事情做好。

学习

今年在看了一些别人的源码后,突然理解一个包/项目应该是怎么写的,感觉Python的水平提高了不少(只是自我感觉良好哈哈哈);然后今年由于项目要用到R,终于在自己默默学习了R很久之后,会写一些R脚本了,果然实践是检验真理的唯一标准。

不过由于搬家后是地铁通勤,所以没有再像以前一样,上班途中看视频学习,略有遗憾。

今年终于报考驾考了,目前进度是科目一。。。

消费

  • 跟着mjj,屯了几台vps,自己搭了TTRSS,非常好用,之前想搞Emby/Jellyfin之类,最终放弃了
  • 给自己换了iPhone 11,给女友换了12
  • 投影仪(女朋友先斩后奏送的礼物)
  • 健身环大冒险、动森,还有疫情在家时,买了很多switch卡带玩,比如巫师3,路易基鬼屋等,强烈推荐鬼屋,女友通关后又将所有宝石收集完
  • 小熊料理锅,自己在家烤肉/烤鱼,搬家后还请爸妈来吃了一顿烤肉,二老也很喜欢这个锅

图 2. 小熊料理锅

输出

我在语雀上建了个“好物分享”的知识库,用来分享自己觉得好的、值得分享的网站、软件等,特别是在分享轻芒杂志的邀请码后,竟然有很多朋友使用了我的邀请链接,所以分享还是有价值的;来年我会继续更新。

今年也参与了思考问题的熊举办的“素材学习分享周刊”小组,贡献了自己的一期,也收获了很多大佬分享的干货。

生活里很多内容都是在工作中学习到的,但由于工作内容保密的原因,之前很多想写的博客都没有动手,拖的时间久了,自然就觉得可写可不写了;但今年把语雀当作自己的wiki后,确实很方便,一些工作上遇到的问题,可以及时地记录下来,由于是私人wiki,也不用像博客一样要原创才行,大胆地摘录下别人的方法就好;而且过一段时间后,如果有价值,还可以修改修改,放到博客上。

图 3. Google Analytics 的统计

今年博客只更新了4篇博客,慢慢地我也不强求自己每年更新多少篇,只希望自己之后有更多有价值的想法和经验可以分享给大家。今年没有参加到farbox 2.0的内测,然后自己抄了spencerwoo的博客,搬到Vercel上用Gridsome来生成。

生活

今年又搬了一次家,年初的时候,由于疫情的关系,所住的城中村管得比较严,想要回去,便要在村口的关卡,找本地房东来签责任书,但我租的是二手房东那种公寓,二手房东也在外省回不来,本地一手房东也不愿意出面来担责,而我当时已经拿着行李回到村口了,那些工作人员根本不理会任何解释,只会机械重复地说,让房东出来接你回去;类似的情形,大家在年初返京的新闻同样可以了解到;

正是这种政策,城中村让我觉得毫无人权,所以今年我搬家的时候,就选择了住宅小区,同时也满足了自己想要一个有飘窗的卧室和屋子有个阳台的心愿。但是房租也涨了2倍,而且物价水平也比以前在城中村里高。

今年由于把mbp拿到公司了,所以就用女友的旧笔记本的内存+SSD,捡垃圾组了一台戴9020m的小主机,加上网卡,花了700块钱左右,装上黑苹果,用起来也很舒服;特别是有时候拿去插在投影仪和电视上,当个没广告的电视盒子,因为小机箱,所以特别轻。

图 4. 刘德华的造型

今年看到了《扫毒2》里刘德华的发型,很喜欢那种辫子发型,突发奇想留了一段时间长头发,留的过程自然度过一段时间的尴尬期。但是最近又剪掉了,当然是因为我不够帅,而且留这种发型的人忽然多了起来,就一点都不个性了。

最后是今年的一点小感悟:

  1. 没有什么是永久的,做好准备,拥抱变化
  2. 适合自己的才是最好的
  3. 勿忘本心

2021

明年的目标,

  • 都买健身环了,当然是减肥、减肥再减肥
  • 早日写出自己想要做的那个软件
  • 顺利拿到驾照

最后,祝大家新年快乐,心想事成!

VPS装机记录(3):任务机器人

2020年6月27日 15:52

VPS基本设置好后,开始想在上面放一些自动化的东西,那么我们就需要一个机器人,设想的目的是,我们在常用的社交软件发送一条命令或者设置好的指令,机器人就会在VPS上自动执行,并返回结果。

这种机器人,最好的示例可以参考湾区日报是如何运作的?湾区日报的第一个 “员工”:Slack/Hubot

但是我们暂时实现不了定制化那么高的任务机器人,刚好我在telegram上看到有一个机器人,也比较简单,那么我们就用它来搭建在telegram上的机器人。效果参考下图:

image.png 

image.png

搭建shell-bot机器人

该机器人的repo在botgram/shell-bot,参照作者给的安装流程

创建机器人帐号

点击此链接与Telegram的BotFather聊天,发送 /newbot 指令,然后依照提示给机器人帐号起名字和账号名,然后获得一串HTTP API的token,如:

Use this token to access the HTTP API:
123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11
Keep your token secure and store it safely, it can be used by anyone to control your bot.

安装依赖项

首先,shell-bot是依赖Node.js的,因此先确定你的VPS上安装好了Node.js,使用 npm -v,确认是否已经安装。

然后,如果你是Ubuntu的系统:

sudo apt-get install build-essential git

如果你跟我一样,是CentOS的系统:

sudo yum install make automake gcc gcc-c++ kernel-devel git

安装并运行shell-bot

clone shell-bot的repo,并使用npm安装依赖的包

git clone https://github.com/botgram/shell-bot.git
cd shell-bot
npm install

然后首次运行shell-bot,它会要求你提供token,并且在Telegram的BotFather帐号,会要求你确认是否是你在连接该机器人,最后生成设置文件

node server

当shell-bot运行起来后,在你的telegram,对话你设置好的机器人,如 /help 或者需要执行的命令前加 /run,如 /run uname -a

持久化运行shell-bot

然后我们安装 forever 来持久化运行shell-bot,使用 -g 来全局安装

sudo npm install -g forever

然后在你的 /etc/rc.local 或者开机执行文件里,加入调用的命令,如:

forever start /path/to/shell-bot/server.js

至此,我们的任务机器人就搭建好了,当需要执行某些任务的时候,我们就打开telegram,然后 /run 命令,机器人就会自动帮我们在VPS上执行命令,如果是运行较久的命令,我们则静静等待机器人返回执行结果就好了。该机器人支持的命令,可以使用/help命令,或者在该文件中查看到。

下一篇文章,我会介绍一些服务器监控的APP。


npm install一直报错的解决方法

可能是由于你的Node.js版本太久导致,因此更新Node.js到最新版本,如果你跟我一样是CentOS,需要先更新内核(注意更新内核该操作比较危险,请查清楚后再做,特别是更新后开机项要设置好,不然可能无法开机),然后更新Node.js版本。

更新内核

载入公钥

 rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org

安装ELrepo

yum install https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm # CentOS 7,其他版本不一样

载入 elrepo-kernel 元数据

 yum --disablerepo=\* --enablerepo=elrepo-kernel repolist

更新内核

 yum --disablerepo=\* --enablerepo=elrepo-kernel install  kernel-ml.x86_64  -y

删除旧工具包

yum remove kernel-tools-libs.x86_64 kernel-tools.x86_64  -y

安装新版本工具包

yum --disablerepo=\* --enablerepo=elrepo-kernel install kernel-ml-tools kernel-ml-devel kernel-ml-headers -y

查看内核插入顺序

默认新内核是从头插入,默认启动顺序也是从 0 开始。

grep "^menuentry" /boot/grub2/grub.cfg | cut -d "'" -f2

CentOS Linux (3.10.0-1127.10.1.el7.x86_64) 7 (Core)
CentOS Linux (5.7.2-1.el7.elrepo.x86_64) 7 (Core)
CentOS Linux (0-rescue-96820b9851c24560b5f942f2496b9aeb) 7 (Core)

查看当前实际启动顺序

grub2-editenv list

saved_entry=CentOS Linux (3.10.0-1127.10.1.el7.x86_64) 7 (Core)

设置默认启动

grub2-set-default 'CentOS Linux (5.7.2-1.el7.elrepo.x86_64) 7 (Core)'

重启并检查

reboot
uname -r

更新Node.js

yum remove nodejs npm -y
yum install -y nodejs

Reference

VPS装机记录(2):使用mosh

2020年4月16日 22:43

家里的网络有点差,之前买的VPS,直接连接SSH,输命令时有时卡卡的,于是就想到之前看到过的mosh。引用维基百科的话来介绍一下mosh的特性。

mosh不绑定使用者端的 IP address,这使得使用者从移动网络(像是 3G、4G)与 WiFi 之间切换时,不会造成连线中断。 mosh保持连线开启,当此用者断线时,服务器端只会认定为暂时离线(sleep)让使用者可以稍候连回来。相对的,SSH 因为透过 TCP,在使用者断线时会造成连线中断。 mosh会试着在本地端马上显示使用者所输入的按键,这使得使用者会感觉到更少的延迟。

CentOS安装mosh

CentOS安装mosh比较简单,使用yum install mosh就可以。如果你提示错误,参考Reference里的文章,可能需要先添加源。

另外,如果你之前参考我的文章,服务器的防火墙关闭了多余的端口,那么这时候就要手动打开端口。

因为mosh默认是走UDP协议的,然后默认使用的端口是60000-61000,第一个连接时用的是60000,第二个连接使用的就是60001,以此类推。当然,你也可以手动指定。

firewall-cmd --zone=public --add-port=60000/udp --permanent # firewall添加你选择的ssh端口,--permanent是保存设置,否则下次重启后不生效
systemctl start firewalld # 若firewall未启动,则先启动
firewall-cmd --reload # 重新加载firewall
firewall-cmd --zone=public --query-port=60000/udp # 查看端口是否添加成功,yes表示成功,no表示未添加成功

使用管理员权限执行上面的命令,打开防火墙的端口就可以了,不要相信网上某些文章,将整个防火墙都关掉那种,简直饮鸩止渴。

Mac使用mosh连接服务器

macOS默认是没有安装mosh的,类似于ssh,我们需要mosh连接,要首先安装好mosh,在mac下直接用brew安装。

brew update # 可以不更新
brew install mosh

如果没有修改过服务器的ssh端口,直接以下命令就可以连接;如果参考我的文章,修改过服务器的ssh默认端口的,参考第二条命令来连接;如果你连防火墙的udp端口也修改了,那么参考第三条命令,指定mosh走的udp端口。

mosh username@server_ip # 默认情况下的命令
mosh username@server_ip --ssh="ssh -p 245" # 修改ssh端口为你设置的端口
mosh username@server_ip -P 60011 # -P 指定mosh走的udp端口,如果你只打开了某个udp端口的话

Win使用mosh连接服务器

Win下我习惯使用Termius来登录mosh连接,当然如果你有其他终端软件也可以,如图将mosh的开关打开,然后填入你自己定义的SSH端口,如2222;填入用户名和密码,保存即可。

后言

mosh有其优点,比如对ssh支持很好,安全性也很好;但是也有一些缺点,比如只能刷新一个屏幕,如果你的运行结果超出一个屏幕,无法滚动看回,只能用less来捕获来看了。

另外,我查看mosh的官网,发现mosh在很多不同的平台,都有支持,所以真的很优秀。

Reference

VPS装机记录(1):SSH篇

2019年12月14日 20:07

前段时间趁黑五折扣,买了个小鸡[^1台独立服务器开出来的多台虚拟机,叫作小鸡]来玩,由于是什么都没有的centos系统,因此一切装机都要靠自己来,也顺便记录一下自己的心得。

首先,开启一台VPS后,第一步肯定是登录上去,才能进行后续的操作,而我们的VPS平时放在网上,肯定有一堆无聊的人会去扫端口,密码爆破这种无聊的事情,所以我们第一步是保证服务器的登录安全。

我想要达到的目的是这样的,以下方法均是在centos7上:

  1. 修改SSH默认的22端口
  2. 使用fail2ban去屏蔽多次尝试密码的IP
  3. 禁止root用户直接登录
  4. 使用密码加 Google Authenticator 2步验证进行登录
  5. 或使用有密码的SSH密钥进行登录

1. 修改SSH端口

修改ssh端口需要修改ssh配置、修改firewall配置、修改SElinux配置三个文件,以下均是使用管理员权限执行。

1.1 修改/etc/ssh/sshd_config文件

vi /etc/ssh/sshd_config进入该文件,找到Port 22这一行,然后在下面添加一行如Port 43作为新的端口,注意在确定可以使用新端口登录前,不要注释Port 22这一行,以免无法登录。

1.2 修改firewall配置

firewall-cmd --zone=public --add-port=43/tcp --permanent # firewall添加你选择的ssh端口,--permanent是保存设置,否则下次重启后不生效
systemctl start firewalld # 若firewall未启动,则先启动
firewall-cmd --reload # 重新加载firewall
firewall-cmd --zone=public --query-port=43/tcp # 查看端口是否添加成功,yes表示成功,no表示未添加成功

1.3 修改SELinux配置

这一步有的VPS可能是关闭SELinux的,就不需要修改;但是默认应该是打开了SELinux的,因此推荐修改。

semanage port -l | grep ssh # 查看当前SELinux允许的ssh端口

如果显示semanage command not found,则

yum provides semanage # 或 yum whatprovides semanage
yum -y install policycoreutils-python # 安装
/usr/sbin/sestatus -v # 查看SELinux状态,enabled即为开启状态

若未开启,则vi /etc/selinux/config,将SELINUX=disabled修改为SELINUX=enforcing,需要重启。

semanage port -a -t ssh_port_t -p tcp 443 # 添加ssh端口
semanage port -l | grep ssh # 再执行一次查看是否添加成功

1.4 重启服务,并测试是否成功

systemctl restart sshd  
systemctl restart firewalld.service  
shutdown -r now # 重启机器,最好重启一下

重启后使用新端口进行ssh登录,测试是否添加成功。

ssh usrname@server -p 43 # 使用-p指定端口

登录成功后vi /etc/ssh/sshd_configPort 22这一行注释,并继续重启服务以生效。

2. 使用fail2ban去屏蔽多次尝试密码的IP

修改默认ssh端口后已经可以防御很多只扫描特定端口的脚本,但是还是有被密码爆破的风险,因此我们安装fail2ban来屏蔽多次尝试密码的坏人。

yum -y install epel-release # CentOS内置源并未包含fail2ban,需要先安装epel源
yum -y install fail2ban # 安装fail2ban

vi /etc/fail2ban/jail.local来新建fail2ban的配置,复制以下配置作为默认规则:

[DEFAULT]
ignoreip = 127.0.0.1/8
bantime  = 86400
findtime = 600
maxretry = 5
#这里banaction必须用firewallcmd-ipset,这是fiewalll支持的关键,如果是用Iptables请不要这样填写
banaction = firewallcmd-ipset
action = %(action_mwl)s

[sshd]
enabled = true
filter  = sshd
port    = 43
# 这里的43为你修改后的端口
action = %(action_mwl)s
logpath = /var/log/secure

上面的配置为十分钟内,如果连续错误超过5次,就ban掉这个IP。

输入systemctl start fail2ban启动fail2ban。fail2ban-client status sshd显示fail2ban的状态,查看是否有被攻击的记录。

3. 禁止root用户直接登录

前面由于要修改、安装各种服务,因此使用root账户比较方便。但在VPS的实际使用中,首先我们要避免被坏人攻陷,直接root登录;其次我们要避免使用root用户执行危险的操作,发生意外,所以我们禁止root用户直接登录,新建一个拥有sudo权限的用户,平时使用其来登录和执行操作,减低风险。

useradd newone # 新建名为newone的用户
passwd newone # 设置newone的密码

注意!!!该步骤非常重要,否则新用户可能无法登录。输入vi /etc/ssh/sshd_config,使用AllowUsers newone添加可以ssh登录的用户,systemctl restart sshd重启ssh服务。

修改上一步后,保留一个终端窗口,测试新用户是否能成功登录,如果能成功登录,则禁用root用户登录。vi /etc/ssh/sshd_config修改其中PermitRootLogin yesPermitRootLogin nosystemctl restart sshd重启ssh服务。此时root账户已经无法登录。

4. 使用密码加 Google Authenticator 2步验证进行登录

比较安全的SSH登录方式,一种是禁止密码且只允许密钥登录,只要保证密钥的安全,就能保证登录的安全;而另外一种2步验证的方法了。这里我们会用到Google Authentication,其实很多网站/App已经运用到2步验证了。

4.1 安装Google Authenticator

yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
yum install google-authenticator

切换到要使用Google Authenticator的用户,然后输入google-authenticator,屏幕会显示一个超大的二维码,你需要使用支持Google Authenticator的软件,扫描该二维码或者输入“secret key”以生成动态的验证码。

红色方框就是“secret key”,而绿色方框中是临时密码,这几个密码使用一次就会失效;后面的选择可以参考我的设置;另外,Google Authenticator会在当前用户的home目录生成.google_authenticator文件,如果你需要更换,删掉该文件,然后重新生成即可。

4.2 修改配置

修改pam配置文件,vi /etc/pam.d/sshd,在首行加入auth required pam_google_authenticator.so,这样子在输入密码登录之前,会先要求输入Google Authentication的验证码,如果是希望反过来,则将这行代码写入到pam配置文件的最后则可;

修改ssh配置文件,vi /etc/ssh/sshd_configChallengeResponseAuthentication no修改为ChallengeResponseAuthentication yes

检查系统时间,

#查看下服务器时间
date
#如果时区不一样,再使用命令修改为本地时间
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

最后,在保留一个活动的终端窗口的前提下,重启ssh服务,systemctl restart sshd,然后重新登录该用户测试是否成功(登录失败也有可能是因为终端软件的问题,比如,尝试更换软件)。

5. 使用有密码的SSH密钥进行登录

其实,使用密钥进行登录已经算非常安全了,但是为了更加安全,我们还可以给密钥文件添加密码。建议在自己的常用工作电脑上使用密钥登录服务器,而在其他电脑上则保留使用密码登录的方式。

使用密钥登录,我们会生成非对称加密的一对密钥(不清楚非对称加密是什么?看看阮一峰老师的这篇文章),分别称之为“私钥”和“公钥”。如果公钥加密的信息只有私钥才能解开,那么只要私钥不泄露,通信就是安全的。

(1)乙方生成两把密钥(公钥和私钥)。公钥是公开的,任何人都可以获得,私钥则是保密的。

(2)甲方获取乙方的公钥,然后用它对信息加密。

(3)乙方得到加密后的信息,用私钥解密。

而我们使用密钥来进行登录也是这样,将公钥放在远程要登录的服务器上,从远程发送过来的数据,只有我们在本地的私钥才能解读,从而保证两者之间的通信是安全的。

5.1 生成密钥对

在终端输入ssh-keygen来生成密钥,默认会保存在~/.ssh/id_rsa,可以自定义该文件的地址和名称,例如~/.ssh/remote_server。然后会询问是否添加密钥,默认是不设置密码的,这里我输入了设定的密码。然后会生成密钥文件,其中你指定的路径就是私钥文件,而.pub结尾的就是公钥文件。

然后在本地的~/.ssh/config中添加以下代码,用于指定密钥

Host RemoteServer # 随意自己起,但是要用到
    HostName 102.133.250.111 # 修改为服务器的地址,域名或IP
    User newone # 指定登录的用户
    PreferredAuthentications publickey
    IdentityFile ~/.ssh/remote_server # 指定私钥的地址
    Port 43 # 默认端口为22,如果你修改了端口,则修改为对应的端口

5.2 将公钥存放到目标服务器上

打开目标服务器的目标用户的~/.ssh路径,然后将.ssh/remote_server.pub文件的内容复制到~/.ssh/authorized_keys里,如果没有~/.ssh文件夹则参考以下代码,先localhost登录一次。

$ ssh localhost # 输入密码登录
The authenticity of host 'localhost (::1)' can't be established.
ECDSA key fingerprint is SHA256:DYd7538oOsqpIIDTs01C3G4S6PRE7msA91yUgk9Dzxk.
ECDSA key fingerprint is MD5:88:80:21:03:b2:52:6b:06:ff:c7:3b:d5:2d:47:c9:ad.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'localhost' (ECDSA) to the list of known hosts.
newone@localhost's password: 
Last login: Sat Dec 14 19:49:07 2019 from localhost
$ exit

登录过后就会生成~/.ssh文件夹了。注意~/.ssh目录权限必须为700,~/.ssh/authorized_keys权限必须为600。

5.3 修改配置文件

又来到熟悉的配置文件,输入vi /etc/ssh/sshd_config,将该文件添加以下3行,如果已有则改成一样的。

RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys

然后systemctl restart sshd重启ssh服务。

在本地使用类似ssh newone@RemoteServer的命令进行登录,如果登录成功则说明设置生效了。

至此,我们所希望的5个目标已经完全实现了。

Reference

记录 VEP 关于 COSMIC 注释的一个坑

2019年6月30日 23:22

工作中有用到VEP,确实是一款出色的注释软件。相比ANNOVAR,最大的优点是支持HGVS标准的注释。

可能由于ANNOVAR面世比较早,当时很多变异描述的标准还没有通行,ANNOVAR采取的是按照基因组来left-normalization的方法,而HGVS的标准,则是根据基因/转录本的方向来left-normalization,因此有可能有的基因与ANNOVAR注释的方向相反。在某些地方,如delins的突变,ANNOVAR与VEP的注释也会不相同,当然,我们还是认为两者都是很出色的注释软件。(关于注释软件的比较,可以看看Golden Helix的这篇文章,http://blog.goldenhelix.com/goldenadmin/the-sate-of-variant-annotation-a-comparison-of-annovar-snpeff-and-vep/)

这次,主要是记录一个VEP关于COSMIC注释的坑,避免大家以后踩到。事情的缘由,还是Ryu的一个同事,发现在一个Somatic突变上,VEP注释了多个COSMIC记录,而查证后却发现,很多事不正确的。

比如,我们用编号为COSM476BRAF:V600E来举例:

可见,VEP确实注释了多个COSMIC ID,但只有COSM476才是正确的。What?这是怎么发生的。

于是Ryu就去查VEP的文档,终于被我发现了原因。VEP注释是可以注释COSMIC的记录的,但是这个注释,主要是根据染色体坐标而进行的co-located variants注释,没有判断这个突变是什么碱基变化的。

那么为什么要这么做呢?VEP明显是可以实现分辨碱基突变的功能的。援引VEP的原文,原来Ensembl并没有COSMIC、HGMD等数据库的精细到碱基突变的使用许可协议,因此这些数据能够被注释,但是却是换了一个方法,只能精细到染色体位置的层级。

For some data sources (COSMIC, HGMD), Ensembl is not licensed to redistribute allele-specific data, so VEP will report the existence of co-located variants with unknown alleles without carrying out allele matching. To disable this behaviour and exclude these variants, use the --exclude_null_alleles flag.

看到这里,不禁感叹外国人对于版权的意识。在国内,可能COSMIC的注释,分分钟就被人注释上去了,也不会有人追究。其实ANNOVAR的COSMIC注释也止步更新于V70,而现在的COSMIC版本都已经快V90了。

大家以后使用VEP的时候,不要直接使用注释其中的COSMIC记录哦。

记录一次 Name.com 自动续费成功退款的经过

2019年5月4日 23:22

上个月的某天,我收到 Name.com 的邮件提示,告诉我的一个网站自动续费了;之前我已经收到关于这个域名快要到期的邮件了,但是没想到在域名有效期还剩下一个月左右的时候,Name.com 就帮我自动续费了。

本来我是打算在 Name.com 上续费的,因为 Name.com 续费可以使用优惠码进行打折,而且 WHOIS 隐私服务也可以使用优惠码来兑换,算是挺实惠的。

但是没想到 Name.com 抢先在我之前就自动续费了,而且还是按着全额的价格来续费(可以看到,本来 10.99 刀,而现在 12.99+4.99 刀,多花了将近 7 刀)。

于是我想,不能吃了这个哑巴亏呀,我要尝试一下能不能退款。毕竟 7 刀也差不多够我再买一个新的.com 域名了(Name.com COM 注册为 8.99 刀)。于是我到网上 Google,没想到大部分人说的都是,这是不能退款,有的人说这钱是交给注册局的,有的说域名注册能退但续费不能退,也有的说能退款,但是必须删除掉你的域名,这样注册局才能退钱之类云云。但是我也在网上搜到极少数的说成功退款的经历,主要还是域名注册的。

不管怎么说,不试试怎么知道呢,于是我 Google 了一下退款的工单的例子,然后提交了一份工单。一般外国的服务商上班时间都是国内的晚上,所以提交工单之后,就需要耐心地等待那边上班了。

隔了差不多一天,Name.com 给我回复了,

其中有几个需要注意的点,:

  1. 退款需要在交易的 5 天内完成;
  2. 需要删除我的域名;

同时他也提到,需要我回复确认是否删除域名;另外删除后我可以提交退款单,退款就会打到我的邮箱。

这时我就有点懵逼了,真的如网上所说的,需要删掉我的域名才能给我退款?但是邮件里他的表达又有点含糊其辞,没有表达清楚这个删除是什么意思?是向注册局提交我放弃我的域名(我的域名还有 1 个月左右的有效期)?还是在 Name.com 上删除我的域名?于是我给他回了邮件,希望他再次解释清楚,并且询问是否能不删除域名,只是取消续费的操作。

很快又收到 Name.com 工作人员的回复了,这次他的回复再次表达到,如果需要退款,必须先删除掉我的域名。

但是后面的第二段内容则有点意思了,他说到我可以选择转移域名或者将域名留在这里。这是否意味着,我将域名转移走,也属于在 Name.com 删除我的域名的操作?于是我怀着希望,再次给他回复邮件了。

很快,我又收到了回复,

没错,这次他肯定地答复,如果我在自动续费交易发生的 5 天内完成域名的转移,那么将能够退款给我。OK,那么其实这个时候已经距离自动续费的交易过了有 3、4 天了,而我则需要尽快完成域名转移。

这时候就要使用 domcomp 这个神器了,这个网站,可以查询不同后缀的域名,注册、续费、转移的最便宜的价格的域名服务商有哪些。于是我搜索了.com 转移的最便宜的服务商。

没错,我们能看到,.com 最便宜的转移价格在 1&1 这个网站,价格为 1 刀,其实这里可能由于 domcomp 这个网站的数据有些错误,所以 1&1 的转移价格并不是 1 刀,只是新注册.com 的价格为活动价 1 刀。

但是我之前也有域名在 1&1 上面,于是正好,也免得注册别的了,就转移到 1&1 上面吧,这里不得不夸奖 Name.com 的服务,还有 ** 加速转移域名 ** 的按钮,于是很快我的域名就提交了加速转移了。

接着我就直接提交了退款单,等待 Name.com 的退款了,这时还是有点紧张的,因为已经接近 5 天的限期,而且不知道 Name.com 的工作人员上班处理时间是什么时候,也不知道域名是否已经完全转移成功。

接着我就收到与之前几乎一模一样的回复,于是这次我就回复确认删除且退款。

然后,我就收到了确认退款的回复了,大概需要 3-5 天的时间,退款将会退回到我的信用卡。

最后耐心地等待,就收到银行的退款确认了。可以看到,从自动续费到退款,整个事件在 5、6 天左右。最后称赞一下,Name.com 的服务还是很棒的,工单回复也算及时,而且域名服务有免费的 WHOIS 隐私赠送。

macOS Case Sensitive to Case Insensitive(使用 Carbon Copy Cloner)

2019年2月2日 12:33

最近,入手了 MBP 2018,就想着将旧电脑的数据使用“迁移助理”迁移到新 macbook,但是打开迁移助理后却提示由于旧电脑的文件系统格式是“Mac OS 拓展(区分大小写,日志式)”(Case-sensitive, Journaled),而新 macbook 则是默认“Mac OS 拓展(日志式”(without the Case-sensitive),因此不支持数据迁移。

这可难倒我了,旧电脑使用了很久,里面有很多购买的软件,也有很有程序的设置和文件,如果要手动拷贝到新 macbook 上,无疑是很低效,而且效果也不好的。

初步搜索结果

于是我初步 Google 了一下,先是找到了2种方法:

  • 将新 macbook 格盘成大小写敏感重装系统,再数据迁移(缺点是新 macbook 的文件系统格式变成了大小写敏感)
  • 将旧电脑修改所有大小写重名的文件,做一个 TimeMachine,然后旧电脑格盘成大小写不敏感,再使用 TimeMachine 恢复,最后数据迁移(缺点是较繁琐,且旧电脑的数据被格掉,方法来自 https://github.com/cr/MacCaseSensitiveConversion

先说一下2个方法,第一个方法肯定可行,但是 macOS 默认大小写不敏感是有道理的,很多软件默认不支持大小写敏感的文件系统,比如我装 steam 平台时就遇到过。且目前而言,大小写不敏感的文件系统利大于弊,因此我决定使用大小写不敏感的文件系统,第一个方法被否掉。

第二个方法,其实也算比较冒险且繁琐,需要经历查找-重命名-备份-格盘-恢复-迁移的步骤,而且万一格盘后不能恢复(网上曾见过大小写敏感的 TimeMachine 不能被恢复成大小写不敏感),原始文件都没了。如果没有找到第三个方法,那么我可能被迫只能使用第二个方法了。

另外在Google 过程中,找到一个名为“iDefrag”的软件(旧名称为“iPartition”),有人称是可以进行大小写敏感的转换的,遗憾的是,该软件预计在19年7月份才更新到支持 macOS 10.10以上,因此同样放弃。

解决方法

碰巧的是,当我过了几天,再 Google 搜索时,居然找到有人使用 Carbon Copy Cloner 将文件系统转换成大小写不敏感的经历,虽然是16年的帖子,但是有成功的经历,且我自己看了整个流程后,发现不用格盘,因此信心倍增。

流程如下:

  1. 下载 Carbon Copy Cloner(以下简称 CCC),安装,有30天的试用期,因此完全够用了;

  2. 使用 CCC 将 Mac 系统盘备份到一个大小写不敏感的分区(此步我是在旧电脑的硬盘上分出1个足够大小的大小写不敏感分区,读者使用移动硬盘或者足够大小的 U 盘也是可以的) 磁盘工具 Carbon Copy Cloner

  3. 检查备份是否成功,下图可见大小写重名冲突只是少量文件,因此我推测可以成功 Carbon Copy Cloner Carbon Copy Cloner

  4. 挂载备份盘(备份盘分区时命名为 Recovery HD)

  5. 在“系统偏好设置”中,进入“启动磁盘”,并选择Recovery HD,重新启动 系统偏好设置 系统偏好设置

  6. 以 Recovery HD 重启 mac 系统,登录进入(会发现克隆了一个一模一样的环境,CCC 真强大)

  7. 此时我们已经拥有了一个大小写不敏感的 Mac 系统了,启动迁移助理,成功完成数据迁移!(最后需要提醒,使用数据迁移,尽量使用雷电数据线或者网线进行数据传输,速度将会快很多,70G 的数据迁移,WIFI 下需要12h 以上,网线情况下我只使用了约2h)

参考网页

  1. https://discussions.apple.com/thread/7546003
  2. https://forums.macrumors.com/threads/case-sensitive-to-normal.1969880/
  3. macOS 文件系统的大小写敏感转换

ANNOVAR (2): 关于注释数据库

2018年4月28日 16:17

使用 ANNOVAR 来注释基因组中的突变,首先要下载 ANNOVAR 的注释数据库。如果你需要经常地更新注释数据库,又或者你是“不更新会死星人”,想使用最新的数据库,那么这篇文章也许对你有帮助。

除此之外,ANNOVAR 的注释数据库更新一般会改正一些错误,比如17年10月的一次数据库更新,改正了以前长期存在的 Clinvar 数据库中,同一个 SNP 多种 allele 都注释到同一个突变中的问题,因此使用新的数据库有时也是必要的。

如何下载 ANNOVAR 注释数据库

ANNOVAR 中自带下载注释数据库的程序,使用的方法是:

  1. 先到Download ANNOVAR查找自己需要的数据库,例如Clinvar,找到最新的clinvar_20170905
  2. 然后使用命令annotate_variation.pl -buildver hg19 -downdb -webfrom annovar clinvar_20170905 humandb/
  3. 程序会自动下载该数据库以及索引并解压到humandb文件夹

这样做的好处是 ANNOVAR 会自动将下载好的数据库进行解压,并放到指定的文件夹;但是注释数据库文件的服务器在国外,如果遇到网络不好的情况,经常性地会断开,又要重新下载一遍;并且 ANNOVAR 的程序下载注释数据库是一条命令一个的,十分不方便。

手动下载 ANNOVAR 注释数据库

前面提到过,ANNOVAR 下载注释数据库的命令是一次一个,非常不友好;而且身处国内,有时网络又不好,可不可以手动批量下载 ANNOVAR 的注释数据库,答案是当然的。

ANNOVAR 可以使用命令annotate_variation.pl -buildver hg19 -downdb -webfrom annovar avdblist humandb/来获得可供下载的注释数据库的清单,运行该命令后我们可以获得名为hg19_avdblist.txt的文件,查看该文件我们可以看见所有 hg19版本的注释数据库。该文件分为3列,分别为数据库文件名称、发布日期以及文件大小。

我们观察 ANNOVAR 下载注释数据库时的log如下

可以看见,ANNOVAR的注释数据库下载地址都是http://www.openbioinformatics.org/annovar/download/后面接上需要下载的注释数据库名称(在上图所示的hg19_avdblist.txt文件可以获得),之所以需要下载hg19_avdblist.txt文件是因为http://www.openbioinformatics.org/annovar/download/这个地址无法直接 wget 镜像全站。

由此,我们可以使用 wget或 curl 手动下载注释数据库,例如

wget -P humandb/ http://www.openbioinformatics.org/annovar/download/hg19_clinvar_20170905.txt.gz
wget -P humandb/ http://www.openbioinformatics.org/annovar/download/hg19_clinvar_20170905.txt.idx.gz # 别忘记需要下载注释数据库的 Index
cd humandb/
gzip -d hg19_clinvar_20170905.txt.gz # 下载完后需要解压才能使用
gzip -d hg19_clinvar_20170905.txt.idx.gz

或者直接将需要下载的地址写到一个文件中,然后运行wget -c -i download.txt来批量下载。

订阅 ANNOVAR 更新

ANNOVAR 的注释数据库一般更新得比较慢,而且不定期,如果我们想定期了解 ANNOVAR 注释数据库更新了哪些,甚至是 ANNOVAR 的更新,是不是需要每隔一段时间去查看一次呢?

当然不需要,我们可以使用第三方的服务,只要Kai Wang更新,我们就能收到提醒。

上图我们可以清晰地看到,ANNOVAR 更新了 Clinvar 数据库的注释数据库,从2016年的03月份的版本更新到了17年的10月份的版本,时间跨度这么久,如果人力去监控,肯定费时费力。

但是我们可以使用Follow That Page这个服务,注册该网站后,填写需要监控的页面如http://annovar.openbioinformatics.org/en/latest/user-guide/download/(ANNOVAR 的注释数据库页面)以及扫描频率(一天一次足矣),我们就可以接收邮件提醒,及时了解 ANNOVAR 的更新。

Follow That Page 这个服务免费而且非常稳定,我已经使用了这个服务3年多时间,用来追踪 ANNOVAR 的更新也已经1年多,只要 ANNOVAR 更新,我就能收到提醒;而且这个网站同理可以用来追踪其他的网站,比如某些政府网站的政策公布,这种不定期、没有RSS源而又十分重要的资讯,Follow That Page 可谓屡试不爽。

脚本自动更新

前面我们提到 ANNOVAR 的程序不友好,一次下载一个注释数据库;后面订阅了数据库更新后还是要手动去更新。

为了解决这个问题,我们可以设置一个定时任务,让服务器自动去更新注释数据库了;实现的原理通过比对新旧两者的hg19_avdblist.txt内容,我们能够得到修改的数据库;实现方式类似于Git diff,我是用了 Linux 系统自带的 diff 命令。以下代码仅为演示,请大家根据需求进行优化。

cp hg19_avdblist.txt old_hg19_avdblist.txt #备份旧的数据库列表
annotate_variation.pl -buildver hg19 -downdb -webfrom annovar avdblist ./ #下载新的数据库列表
diff -c old_hg19_avdblist.txt hg19_avdblist.txt \
| grep -E '^\+|^\!' | cut -f1 \
| sed "s/\! /http\:\/\/www\.openbioinformatics\.org\/annovar\/download\//g;s/\+ /http\:\/\/www\.openbioinformatics\.org\/annovar\/download\//g" > download.txt #获取修改过的数据库,写入 download.txt
wget -c -i download.txt #下载数据库

将以上命令设置为定时执行,就可以自动更新 ANNOVAR 的注释数据库了。

以上内容,如果有误或者有好的 idea,欢迎大家留言,谢谢。

伊恩结

2016年5月15日 05:01

受『比特新声』安利,平日里会时不时地看一下『利器』,这是『离线』杂志搞的一个网站,一开始是采访优秀的创造者,邀请他们来分享工作时所使用的工具,以及使用工具的方式和原则;然后慢慢丰富到有周报,群分享等内容,可以说是越来越丰富。

今天就给大家安利一发这个『伊恩结』!伊恩结是在『利器』的某一期周报看到的。众所周知,我们现在系鞋带用的最多的应该是蝴蝶结。蝴蝶结其实不算方便,而且容易松开;而这个伊恩结却有着蝴蝶结相似的系法(所以有着相似的外观),而且说不会松开不会比蝴蝶结不容易掉。所以还是有学习的价值的。

伊恩结

如何系一个“伊恩结”?简单来说,俩手拇指和食指各拿根鞋绳,一边正转,一边反转,然后一系就可以了。

豆豆 | 程序猿:推荐个系鞋带的方法,好看不松。就比蝴蝶结多绕一次,系出来还是比较美观的,剧烈运动也不会松。

上图还是看不懂,没关系,很正常,看看分解步骤:

伊恩结分解步骤

实测效果熟练后确实会比蝴蝶结要快,但是还是有松开的情况。

Reference:

Pileup Format 学习笔记

2016年4月18日 06:25

Pileup format is first used by Tony Cox and Zemin Ning at the Sanger Institute. It desribes the base-pair information at each chromosomal position. This format facilitates SNP/indel calling and brief alignment viewing by eyes.

Pileup 格式是桑格中心(Tony Cox and Zemin Ning)提出,描述可用肉眼观察的某一个区域所有reads匹配的情况。

The pileup format has several variants. The default output by SAMtools looks like this:

seq1    272    T    24    ,.$.....,,.,.,...,,,.,..^+.    <<<+;<<<<<<<<<<<=<;<;7<&
seq1    273    T    23    ,.....,,.,.,...,,,.,..A    <<<;<<<<<<<<<3<=<<<;<<+
seq1    274    T    23    ,.$....,,.,.,...,,,.,...    7<7;<;<<<<<<<<<=<;<;<<6
seq1    275    A    23    ,$....,,.,.,...,,,.,...^l.    <+;9*<<<<<<<<<=<<:;<<<<
seq1    276    G    22    ...T,,.,.,...,,,.,....    33;+<<7=7<<7<&<<1;<<6<
seq1    277    T    22    ....,,.,.,.C.,,,.,..G.    +7<;<<<<<<<&<=<<:;<<&<
seq1    278    G    23    ....,,.,.,...,,,.,....^k.    %38*<<;<7<<7<=<<<;<<<<<
seq1    279    C    23    A..T,,.,.,...,,,.,.....    ;75&<<<<<<<<<=<<<9<<:<<

where each line consists of

  1. chromosome, 染色体
  2. 1-based coordinate, 染色体上的位置
  3. reference base, 该位点参考序列上的碱基
  4. the number of reads covering the site, 覆盖度(测得reads的数目)
  5. read bases and base qualities. 该位点的每条reads与该位点的匹配方式
  6. mapping quality 匹配质量 (Phred quality score from 0 to 93 using ASCII 33 to 126 (although in raw read data the Phred quality score rarely exceeds 60, higher scores are possible in assemblies or read maps))

read bases column

  • . stands for a match to the reference base on the forward strand 代表匹配到正链
  • , for a match on the reverse strand 代表匹配到负链
  • ACGTN for a mismatch on the forward strand 大写的ACGTN代表与reference的正向链上不同的实际碱基的5种情况
  • acgtn for a mismatch on the reverse strand 小写的acgtn代表与reference的反向链上不同的实际碱基的5种情况
  • A pattern \+[0-9]+[ACGTNacgtn]+ indicates there is an insertion between this reference position and the next reference position. The length of the insertion is given by the integer in the pattern, followed by the inserted sequence.
    • seq2 156 A 11 .$......+2AG.+2AG.+2AGGG <975;:<<<<<中的+2AG有3处,代表有3个read上有AG的2个bp的插入
  • Similarly, a pattern `-[0-9]+[ACGTNacgtn]+' represents a deletion from the reference.
    • seq3 200 A 20 ,,,,,..,.-4CACC.-4CACC....,.,,.^~. ==<<<<<<<<<<<::<;2<<同理,此处的-4CACC有2处,代表有2个read上有CACC的4个bp的缺失
  • a symbol ^ marks the start of a read segment which is a contiguous subsequence on the read separated by N/S/H CIGAR operations.
    ^代表刚好是read的开头
  • The ASCII of the character following ^ minus 33 gives the mapping quality. ^后面跟着的符号表示比对的质量(ASCII码减33)
  • A symbol $ marks the end of a read segment. $代表刚好是read的结尾

reference

❌
❌