Exomiser这个工具,我在实验室里折腾了整整两个周末才算把它彻底驯服。它是一款非常成熟的遗传病变异注释与候选基因排序工具:你给它一个VCF文件,再输入患者的HPO表型词条,它能够自动完成变异注释、人群频率过滤、致病性评估、遗传模式匹配,最后基于表型相似度算法把候选基因排好序输出。对于做罕见病、遗传病外显子组或者全基因组分析的团队,这套流程几乎是绕不开的标准配置。
这篇笔记我从零开始写,把安装JDK、下载发布包、准备数据库、写分析配置文件、跑通第一个样本,以及过程中遇到的各种报错和解决思路完整记录。适合第一次接触Exomiser、被Java环境和数据文件搞得焦头烂额的人,也适合已经装好但卡在某一步始终跑不通的朋友。内容不装深沉,全部是实操记录。
1. Exomiser的定位:它到底解决什么问题
1.1 从原始VCF到候选基因排序的自动化
以前没有这类工具的时候,我们拿到一个外显子组测序的VCF,流程大概是这样:先用VEP或者ANNOVAR把位点注释一遍,然后根据人群频率数据库筛掉常见变异,再结合ClinVar、OMIM这些致病性数据去人工判断,最后还要回到患者表型,靠经验猜测哪个基因更可能致病。整套流程费时费力,而且不同人筛出来的结果还不一样。
Exomiser做的事情就是把这套完整的判断流程固化成一个标准化的分析管线。它会自动对VCF进行转录本注释,判断变异落在基因的哪个区域、产生什么功能影响,然后依次执行质量过滤、频率过滤、致病性过滤、遗传模式过滤,最后用HPO表型相似度算法对通过过滤的基因做排序。最终输出的结果里,最有可能致病的基因排在最前面,还附带详细的证据链,可以直接拿去写报告或者做下一步Sanger验证。
这一步非常关键:它不只是“注释工具”,还是一个“决策辅助系统”。很多人在网上问“我有了SnpEff/VEP还需要Exomiser吗”,我的看法是,如果只是做变异注释,SnpEff够了;但如果你想在几十个候选变异里找出最有可能导致患者表型的那一个,Exomiser这类优先排序工具才是真正的生产力。
1.2 安装的整体思路:其实是一个Java应用程序
Exomiser本质上是一个Java命令行程序,核心逻辑封装在lib目录下的一堆jar包里。它不像Python工具那样可以通过pip直接安装,也不像大多数生信软件那样编译安装,它需要你自己去准备三样东西:能够运行它的Java环境、包含注释和排序数据的数据库文件、以及一份描述分析任务的YAML配置。
这三样东西对应着三层准备:
- Java运行环境:Exomiser新版要求Java 17及以上,JDK必须是17,不是说你机器上随便装个Java就能跑,版本不够直接启动失败。
- 数据文件:包括HPO表型本体数据、变异频率数据库(gnomAD等)、致病性数据库(dbNSFP等)、以及预构建好的变异数据库(H2格式或PostgreSQL)。这些数据体积很大,下载和校验是安装过程中最容易翻车的环节。
- 分析配置:一个YAML文件,告诉Exomiser样本VCF在哪、基因组版本是什么、患者的HPO表型ID有哪些、使用哪些过滤步骤和排序算法。
我在安装之前其实没有意识到数据版本对齐这么重要,结果后续跑了三次全是空结果,白白浪费了一个下午。所以下面整个安装流程,我会把“版本对齐”和“数据准备”当成核心重点反复强调。
2. 安装前的硬性准备:环境、内存与依赖
2.1 Java环境安装:不要装错版本
Exomiser 14版本对应的是Java 17,我自己用的就是OpenJDK 17,稳定运行没出过兼容问题。如果你的Linux服务器上还没有Java,先搞定这一步:
sudo apt update sudo apt install -y openjdk-17-jdk java -version正常会输出类似:
openjdk version "17.0.11" 2024-04-16 OpenJDK Runtime Environment (build 17.0.11+9-Ubuntu) OpenJDK 64-Bit Server VM (build 17.0.11+9-Ubuntu, mixed mode, sharing)如果你的机器上已经存在其他版本的Java,比如Java 11或者Java 8,建议用update-alternatives切换一下默认版本,或者直接在启动脚本里显式指定JDK路径:
sudo update-alternatives --config java这里有一个特别容易忽略的点:很多服务器上虽然装了JDK 17,但用户的PATH环境变量还指向旧版本;你用java -version看到的是17,但Exomiser启动脚本调用的可能是另一个目录底下的Java。所以如果启动报错了,先用which java看一下实际调用路径,再用readlink -f $(which java)确认最终指向。
提示:我踩过一次坑,服务器上同时装了多个JDK,Exomiser启动直接报UnsupportedClassVersionError。排查半天才发现是PATH里先命中了旧版本。别嫌麻烦,安装前统一版本环境能省一大段时间。
2.2 内存、磁盘与基础工具
Exomiser对内存的要求取决于你的数据规模和运行模式。如果只是一个几百MB的精简VCF加最小数据集,4GB内存勉强能跑;但如果你是跑全外显子组,而且启用了hiPhive表型排序算法,内存肯定不够。个人建议:内存至少要给8GB,能到16GB以上最舒服。
磁盘空间更加关键。不同版本的数据库文件体积差异很大,光是变异注释数据库可能就有几十GB甚至上百GB;如果再把gnomAD频率数据、dbNSFP致病性数据、HPO表型数据都下载完整,预留300GB是比较稳妥的做法。很多人在安装时没有提前规划磁盘,结果下载到一半就爆盘,还得从头再来。
安装前建议先把常用工具准备好:
sudo apt install -y git curl wget unzip htop另外,Exomiser分析输入通常要求VCF文件经过bgzip压缩并建好tabix索引,所以htslib相关的两个工具必须装好。最省心的方式是用conda/mamba:
conda install -y -c bioconda bcftools htslibbgzip和tabix在这套工具链里默认带上了。如果不想用conda,也可以用apt:
sudo apt install -y tabix bcftools这两个工具后面处理VCF的时候会用到,别省。还有一个容易被忽略的小工具是md5sum,下载完大数据文件后校验完整性全靠它。
2.3 网络与下载策略
Exomiser的数据文件放在官方网址下,国内访问速度忽快忽慢。直接浏览器点下载风险很大,中断了就得重来。我更推荐用wget的断点续传模式,比如:
wget -c https://data.monarchinitiative.org/exomiser/current/exomiser-data-2302.zip-c参数很关键,万一下到一半断了,不用从头下载。如果网络实在不稳,还可以改用aria2c或者用screen/tmux把下载任务放到后台。大数据文件下载耗时以小时为单位,建议不要在前台终端硬等。
下载完成后马上做校验:
md5sum exomiser-data-2302.zip和官网提供的MD5值比对,不一致就说明包损坏,解压也会报错,一定不要强行使用。
3. 正式安装:下载、解压、目录结构解读
3.1 获取Exomiser发布包
Exomiser的发布包可以从GitHub Releases页面下载,也可以从官网的下载页获取。我用的版本是14.0.0,下载命令:
wget -c https://github.com/exomiser/Exomiser/releases/download/14.0.0/exomiser-cli-14.0.0.zip unzip exomiser-cli-14.0.0.zip cd exomiser-cli-14.0.0解压后目录内容大致是这样的:
exomiser-cli-14.0.0/ ├── bin/ │ └── exomiser-cli ├── lib/ │ └── *.jar ├── core/ ├── data/ │ ├── run_phenotype.sh │ ├── run_download.sh │ └── README.md ├── examples/ │ └── *.yml └── application.properties这里面最重要的是bin/exomiser-cli启动脚本,其次是data目录下的两个数据下载脚本。lib目录里的jar包就是Exomiser的所有核心代码,不需要额外编译,也不需要Maven环境。很多人被网上的旧教程误导,以为要自己拉源码编译,其实完全没有必要。
3.2 application.properties配置:数据版本的对齐从这里开始
解压后的根目录里有一个application.properties文件,这是所有配置的关键入口。我最初的配置是这样:
exomiser.data-version=2302 exomiser.h2.db.location=/data/exomiser/data exomiser.h2.db.prefix=exomiser逐项解释一下:
exomiser.data-version:指定数据版本号。这个必须和你下载的数据库文件版本完全一致。我当时下载的是2302版本(代表Ensembl 2023年2月左右的数据),那这里就必须写2302。写错的话,程序在注释阶段会告诉你找不到对应的转录本数据库。exomiser.h2.db.location:H2数据库文件的存放路径。建议用绝对路径,避免相对路径解析出问题。exomiser.h2.db.prefix:数据库文件前缀,默认一般是exomiser,如果你没有特别定制,保持默认即可。
这里要解释一下H2是什么。Exomiser默认使用H2作为内嵌数据库,它把每个VCF区域的变异注释和频率、致病性信息都预构建在本地文件里。这种设计的好处是部署简单、不依赖外部数据库服务;坏处是数据文件体积大,而且版本一旦配对错,程序就罢工。
如果你后续准备生产环境大批量跑样本,Exomiser也支持PostgreSQL,性能上会更稳定,但配置和初始化复杂不少。我的建议是:第一次安装先用H2把流程跑通,确认分析逻辑没问题,再考虑升级到PostgreSQL。新手千万不要一开始就上PostgreSQL,排错成本高。
3.3 验证安装是否可用
在配置数据之前,先验证程序和Java环境是否正常:
./bin/exomiser-cli --help正常情况下会打印出Exomiser的CLI帮助信息,包括--analysis、--outdir等参数说明。如果这里直接报错,说明Java环境有问题,回到上一步检查JDK版本。
注意:不同的Exomiser版本对Java版本要求不一样。13版本开始要求Java 17,12及更早版本可能Java 11就能跑。安装前一定先看发布说明,别拿新版本配旧Java,或者反过来。
4. 数据库初始化与注释数据准备:最容易翻车的一步
4.1 数据文件获取方式:脚本优先还是手动下载
Exomiser根目录下的data脚本提供了一种相对自动化的数据准备方式。你可以先看看脚本内容:
cat data/run_phenotype.sh脚本里定义了要下载的文件列表和版本号。如果你要自己控制下载,也可以在官网手动下载。这里我强烈建议用脚本,因为脚本会把目录结构和文件名整理好,不容易出错。
运行脚本前要确认版本号是否和application.properties一致。比如run_phenotype.sh里面写的是2302,application.properties里也必须是2302:
cd data ./run_phenotype.shphenotype数据下载完大概需要几分钟到几十分钟,取决于网络。接着再看run_download.sh:
./run_download.sh这个脚本会下载变异频率、致病性等核心数据,体积更大,耗时长。下载完后数据目录下应该是这样的结构:
data/ ├── 2302/ │ ├── exomiser.2302.db │ ├── gnomad... │ ├── dbNSFP... │ ├── hp.obo │ └── ...务必检查最终的数据库文件是否出现在对应版本号目录下。
4.2 H2数据库路径和权限问题
application.properties里配置的exomiser.h2.db.location必须指向包含数据版本目录的路径。比如你的数据放在/data/exomiser/data/2302/exomiser.2302.db,那配置就应该是:
exomiser.h2.db.location=/data/exomiser/data注意,这里填的是上层目录,不是具体的2302目录,更不是数据库文件本身。版本号靠前面的exomiser.data-version来匹配。
运行用户对数据库目录必须有读写权限。我用root跑没问题,但如果用普通用户跑,一定要先chown或者chmod:
sudo chown -R $USER:$USER /data/exomiser否则程序会在初始化H2连接时抛出Access is denied或者类似错误,看起来像数据损坏,其实只是权限问题。
4.3 数据版本不匹配的典型报错
版本不匹配的情况有两种。第一种是application.properties里写的版本号和实际下载的数据版本不一致,运行时会提示找不到对应版本的数据文件。第二种更隐蔽:数据版本匹配了,但你的VCF用的是GRCh38参考基因组,下载的数据库却是基于GRCh37构建的,这时候变异注释结果会大面积为空或者坐标对不上。
解决办法:下载数据之前,先确认你们实验室的VCF是GRCh37还是GRCh38比对出来的。Exomiser数据在官网上一般会标注对应的基因组版本,选数据和配置时保持一致。
实操心得:我推荐把数据下载和版本选择固定下来,比如团队内部就统一用2302 + GRCh38。不要在跑不同项目时频繁切换数据版本,否则之前的结果复现很麻烦。
5. 第一个分析任务:配置YAML并跑通全流程
5.1 最小analysis配置示例
数据准备好了,下一步就是写分析配置文件。Exomiser用YAML描述整个分析流程。我拿一个最简单的配置来看:
analysis: vcf: /data/raw/sample.vcf.gz genomeAssembly: GRCh38 hpoIds: - HP:0001166 - HP:0004322 analysisMode: full inheritanceModes: AD: 0.1 AR: 0.1 MT: 0.1 frequencySources: - gnomad pathogenicitySources: - dbNSFP steps: - failedVariantFilter: {} - qualityFilter: {} - variantEffectFilter: {} - frequencyFilter: {} - pathogenicityFilter: {} - inheritanceFilter: {} - omimPrioritiser: {} - hiPhivePrioritiser: {}这个配置的含义是:读取/data/raw/sample.vcf.gz这个VCF,参考基因组是GRCh38,患者具有两项HPO表型(HP:0001166是指蜘蛛指/趾这一类特征,HP:0004322是身材矮小,这里只是示例,实际要根据患者真实表型填写),分析模式为full,遗传模式考虑常染色体显性、常染色体隐性和线粒体遗传,过滤步骤从质量过滤到遗传模式过滤,最后用OMIM和hiPhive算法进行候选基因排序。
首次跑的时候,最好把步骤精简一些,比如暂时去掉hiPhivePrioritiser只保留omimPrioritiser,这样运行速度快,方便验证整体流程。hiPhive算法涉及表型相似度计算,比较吃内存和CPU,后面再逐步加上去。
5.2 运行命令与输出结果解读
配置完成后执行:
./bin/exomiser-cli --analysis=analysis.yml --outdir=/data/result/sample1第一次运行看到日志里一堆INFO级别的输出不要慌,那是程序在加载数据库和运行注释。当看到类似Process completed字样的日志时,说明跑完了。
输出目录里会生成几个主要文件:
sample1.exomiser.html:可视化报告,浏览器打开就能看候选基因排序和变异列表。sample1.exomiser.tsv:表格化结果,每一行是一个基因的排序信息,方便Excel进一步处理。sample1.exomiser.vcf.gz:带注释的VCF文件,包含Exomiser加上的ANN注释字段。sample1.variants.tsv:通过过滤的变异明细表。
看结果的时候我习惯先打开TSV,按score列排序,最上面的就是Exomiser认为最可能致病的基因。然后点开HTML报告,对比排序理由和证据来源,判断是否符合临床预期。
5.3 VCF预处理:bgzip和tabix索引必须做
如果VCF是普通未压缩的文本格式,Exomiser通常会报错说文件不是压缩格式或者缺少索引。标准做法是:
bgzip -c sample.vcf > sample.vcf.gz tabix -p vcf sample.vcf.gz这里有个细节:bgzip虽然和系统自带的gzip用法相近,但它是Block GZip格式,tabix要求必须用bgzip处理,不能用普通的gzip。如果你拿gzip压缩的VCF直接建索引,后面很可能报File format error或者invalid tid之类的错误。
5.4 运行时报错No variants left怎么办
跑完以后发现输出文件里一个变异都没有,这个问题新手基本都会遇到。官方配置里failedVariantFilter会过滤掉没有正确注释的变异,如果你的VCF染色体编号和数据版本不匹配,这一步会把所有变异都滤掉。比较常见的坑是:
- VCF里的contig是
chr1,而数据里是1,或者反过来。 - VCF样本来自GRCh37的BAM,但数据分析却指定了GRCh38。
- gnomAD频率数据库选得太严,把所有变异都当作高频变异过滤掉了。
排查的时候从原始VCF开始,逐步减少过滤步骤,看到底是哪一步把所有变异滤光的。我一般会用一个小VCF(比如只包含一个基因区域的位点)来做快速验证,能大幅缩短反馈周期。
实操心得:第一次跑Exomiser,千万不要一上来就丢一个全外显子组VCF进去。先用几个突变位点的小VCF把流程跑通,再上全外显子组数据。全外显子的VCF光注释阶段就要跑很久,如果配置有错,浪费的是好几个小时。
6. 安装与运行中的Bug排查实录
6.1 启动报错:UnsupportedClassVersionError或找不到主类
这类错误几乎是Java应用最经典的启动失败原因。出现UnsupportedClassVersionError时,通常说明当前Java版本低于Exomiser要求,消息里会有一串形如class file version 61.0的提示,其中61.0对应Java 17。解决方式就是安装JDK 17并确保启动脚本使用的是它。
还有一种是Could not find or load main class org.monarchinitiative.exomiser.cli.Exomiser。这个错误多半是lib目录下的jar包缺失或者被破坏了。重新解压发布包可以解决。不建议自己从源码编译,Exomiser的构建过程依赖较多,容易在依赖解析上卡壳。
6.2 运行到一半内存溢出
内存溢出最常见的表现是运行一段时间后程序直接退出,日志尾部出现java.lang.OutOfMemoryError: Java heap space。
解决办法是增大JVM堆内存。可以在启动时通过环境变量传入,也可以直接修改bin/exomiser-cli脚本里的JAVA_OPTS或-Xmx参数。我习惯手动设置:
export JAVA_OPTS="-Xms4g -Xmx12g" ./bin/exomiser-cli --analysis=analysis.yml --outdir=/data/result/sample1具体给多少取决于机器配置。12G是个人感觉比较舒服的起点。如果数据版本较新、变异位点多,可以再往上升到16G。堆内存不要超过物理内存减去系统和其他服务所需的内存,否则会触发系统级OOM,反而不稳定。
6.3 VCF注释结果为空,但程序没有报错
程序正常跑完,结果文件里却没有实际变异,这种情况属于“软故障”。我整理一下需要逐步排查的地方:
- 确认VCF确实包含变异记录,并且变异所在的contig命名与数据版本一致。
- 确认VCF已经用bgzip压缩并tabix建索引,检查
.tbi文件和.vcf.gz文件是否在同一目录。 - 确认配置里的
genomeAssembly与数据版本匹配。 - 确认
failedVariantFilter是否把变异全部过滤了,可以用一个已知致病位点的VCF做对照测试。 - 确认HPO表型ID是否存在且属于当前HPO版本。
为了方便排查,可以在配置里临时注释掉几个过滤步骤,跑一次对比结果。这种二分法排查虽然土,但非常有效。
6.4 HPO表型词条无效,导致排序步骤效果差
如果你在使用hiPhivePrioritiser时发现报告里有大量No phenotype data或者HPO term not found的警告,多半是HPO ID填得不规范。HPO本体经常更新,有些旧ID可能已经被废弃,有些则合并到了其他词条。
验证方法很简单,去HPO官网搜索一下你填写的ID,确认它是当前有效的Term。另外,填表型的时候不要只填一个HPO,最少要有3到5个能反映患者核心临床特征的表型词条,排序算法才有足够的信息量。我见过有人只填一个“发育迟缓”就跑去跑hiPhive,出来的排序结果基本没有参考价值。
6.5 数据下载不完整或校验和不一致
数据文件下载一半失败是家常便饭。比如某个850MB的文件最终只有600MB,Exomiser启动时可能不报错,但真正分析时就会因为缺数据而空手而归。所以下载后一定要校验。
md5sum 2302/*.db然后和官网的MD5列表核对。如果不一致,建议删除重下。用wget的-c虽然能断点续传,但如果服务端文件本身已经损坏,续传也没有意义。
6.6 中文路径和用户名引发的血案
国内服务器的用户名经常是拼音或者带中文,项目目录也可能直接用中文命名。Exomiser对这类路径的处理并不友好,可能出现乱码、找不到文件、字符编码报错。
最稳妥的做法是统一使用纯英文路径,而且不要有空格。比如:
/data/exomiser /home/zhangsan/exomiser如果已经遇到了奇怪的编码错误,检查系统locale设置,尽量使用en_US.UTF-8或者C.UTF-8环境运行,不要使用zh_CN.GBK这类旧编码。
6.7 备用方案:用Docker绕开本地依赖地狱
本地Java环境、权限、数据版本、系统库互相纠缠,有时候确实让人崩溃。如果你急着跑数据,可以试试Docker方案:
docker pull exomiser/exomiser:latest然后通过挂载目录的方式运行容器。Docker的好处是镜像里已经把Java环境和Exomiser打包好了,你不用在宿主上处理JDK版本冲突。但要注意,数据文件仍然需要自己准备并挂载进容器,Docker只是解决运行环境问题,不解决数据版本问题。
6.8 Bug排查速查表
| 报错或异常现象 | 常见原因 | 解决建议 |
|---|---|---|
| UnsupportedClassVersionError | Java版本过低或PATH环境变量指定了旧JDK | 安装JDK 17并切换默认java |
| Could not find or load main class | lib目录缺失或jar包损坏 | 重新解压Exomiser发布包 |
| Java heap space | 堆内存设置不足 | 设置JAVA_OPTS为-Xmx12g或更高 |
| 结果无变异 | VCF未压缩建索引或contig命名不一致 | bgzip+tabix处理VCF,核对基因组版本 |
| HPO Term not found | HPO ID废弃或不存在 | 在HPO官网核对有效Term |
| Access denied | 数据库目录无写权限 | chown/chmod授权 |
| 数据版本找不到 | application.properties版本与数据文件不一致 | 统一配置和数据版本号 |
| 中文路径报错 | 路径编码问题 | 使用纯英文无空格路径 |
尾巴:一点个人体会
整套装下来,我的感受是Exomiser本身并不难装,真正的门槛在数据准备和版本对齐。如果你愿意先把Java环境理清楚、提前规划好数据目录和磁盘空间、第一次跑都用小VCF验证流程,整个过程会顺利得多。我现在每台新服务器都会先写一个安装清单,把JDK版本、数据版本、目录结构、YAML模板固定下来,以后重新部署基本半小时内搞定。
最后再分享一个小技巧:Exomiser的数据版本不要频繁追新。新版本数据确实更全,但团队内部一旦有人用了新数据,生成的注释结果和旧数据会有差异,后续数据管理会很头疼。选择一个稳定版本,让整个团队统一使用,比追最新版本要重要得多。