久しぶりにTophatをいじったら一発目でエラーで落ちてしまい,出鼻をくじかれてしまった….原因を調べてみると,どうやらTophatのコマンド実行時に指定する-pオプションの数字を調子に乗って上げすぎたのが良くなかったらしい.といっても計算機のリソースに問題があったわけではなく,ユーザが使えるシステムリソースの制限を超えてしまったために,Tophatが停止してしまったようだ.この問題はTophatの公式サイトのFAQでも取り上げられているが,このBlogでもエラーメッセージとともに原因と対策を書いておこうと思う.
Tophatの標準エラー出力のメッセージ
今回の場合は,Tophatのログの最後で以下のようなエラーメッセージが表示される.
1 2 3 4 5 6 7 |
|
これだけでは何のことだかよくわからないが,Tophatが出力するログのlogs/segment_juncs.logを見ると,このエラーに関してもう少し詳細な記述が出力されている.
1 2 3 4 5 6 7 8 9 |
|
これを見ると,どうやらsegment_juncsの実行中に「open: Too many open files」が原因で実行が落ちたようだ.
原因と対策
このエラーに関しては,実はTophatの公式サイトのFAQに「What should I do if I see a message like “Too many open files”?」という,まさに先ほどのエラーメッセージの内容そのままの項がある.
This usually happens when using “-p” option with a large value (many threads). TopHat may produce many intermediate files, the number of which is proportional to this value; sometimes the number of the files may go over the maximum number of files a process is allowed to open. The solution is to raise the limit to a higher number (e.g. 10000). For Mac, you can change this using a command, “sudo sysctl -w kern.maxfiles=10240”.
TopHat :: Center for Bioinformatics and Computational Biology
ざっと要約すると「Tophatは中間ファイルを大量に作るから時々許容数超えちゃうんだよね.扱えるファイル数の上限上げるか,Macなら次のコマンドで対処してね」ということになる.さすがにこれだけではよく分からないと思うので,SEQanswersの以下のスレッドも参考にしつつ,もう少し詳しく見ていこうと思う.
Tophat segment junction error 1, invalid BAM binary header - SEQanswers
limitとファイルディスクリプタ数の制限
さて,公式サイトのFAQにおいてファイル数の上限といった言葉が出てきたように,LinuxやMacではユーザごとに使用することのできる各種システムリソースに制限が設けられている.具体的にはユーザが使用できるCPU数やメモリの容量,プロセスの数などがそれに該当するのだが,その中に「ファイルディスクリプタ数」という項目があり,1プロセスが同時に開くことのできるファイル数の上限を定めている.これは主にひとつの計算機を複数人が使用するマルチユーザシステムにおいて,一人がリソースを独占するのを防いだりアプリケーションの暴走を止めたりするのに役立つのだが,今回のような大規模な計算を実行する際にはこれが邪魔になってしまう.
システムリソースの制限を確認したい場合には,「ulimit -a」または「limit」というコマンドを使う.例えば,私の環境では以下のようになる.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
ここで表示されるのは厳密にはソフトリミットと呼ばれ,ユーザごとに設定されている制限である.一方でハードリミットと呼ばれる制限もあり,これは管理者(root)が定める制限となっている.ソフトリミットは,このハードリミットの範囲内でしか自由に制限値を変更することはできない.ハードリミットを確認したい場合には,-Hオプションを付ける.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
さて,今回問題になっているファイルディスクリプタ数は「-n: file descriptors」で表示されている.上の例の場合,ソフトリミットでは1024,ハードリミットでは4096となっている.つまり,Tophatは1024個以上のファイルを1スレッドで開こうとしたために,このソフトリミットに引っかかってしまったようだ.
フィアルディスクリプタ数の制限への対策
この問題を回避するには主に2つの方法がある.
1.Tophatの-pオプションの値を小さくする
2.ソフトリミットのファイルディスクリプタの値を大きくする
まず1.では,Tophatが使用するスレッド数を少なくすることで,ファイルディスクリプタ数の上限に引っかからなくするというもの.一度-pオプションを無くして実行してみれば,おそらく今回のエラーには引っかからなくなるだろう.一度に開くファイル数が少なくなりほぼ確実に実行できるようにはなるが,並列処理数が減ってしまうのでTophatの実行時間は長くなってしまう.
そこで2.のようにの制限を無くして,-pオプションはそのままにファイルディスクリプタの上限を回避するという方法もある.実行コマンドや実行時間はそのままにエラーを回避することができる一方で,上限を上げたからといってもTophatがそれ以上の同時ファイルオープンをしてしまえば同様のエラーに引っかかってしまうほか,制限を上げたことにより計算機に負荷がかかる恐れもある.つまり,時と場合によっては成功するが確証は無いという感じだろうか.
ちなみに,私の場合はファイルディスクリプタ数を上げても以下のような別のエラーが出て実行できなかった.
1
|
|
ということで,結論としてはTophatの実行時間との兼ね合いを考えて,どちらかを選択したほうが良いだろう.素直に-pオプションの値を下げるほうが無難な気がする.
ちなみに,制限値を引き上げるには,ulimitで以下のように値を変更する.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
ulimitの後ろに該当するパラメータの値を指定することによって,上限を引き上げることができる.ただし,先ほど述べたようにハードリミットより上は指定することができないので注意が必要になる.
まとめ
Tophatのエラー「open: Too many open files」は,スレッドが一度に開くことのできるファイルディスクリプタ数がソフトリミットの上限に引っかかってしまったために起こる.-pオプションの値を下げて実行するか,ソフトリミットのファイルディスクリプタの上限を引き上げることによって回避することができる.まずは,-pオプションを指定せずに実行してみよう.
参考
- TopHat :: Center for Bioinformatics and Computational Biology
- Tophat segment junction error 1, invalid BAM binary header - SEQanswers
- UNIXの部屋 コマンド検索:limit (*BSD/Linux)
- ファイルディスクリプタ数の上限変更とlimits.confの罠 (ゆめ技:ゆめみスタッフブログ)
実行環境
- OS:RHEL 6.3
- Tophat:v2.0.8b
- Bowtie:version 2.1.0
- Samtools:0.1.19.0