0
0

GTDBで提供されている系統樹をiTOLで開く

Posted at

背景

微生物の種の系統樹をアノテーションする時に、GTDBから取得した系統樹をiTOLでアノテーションしたいという人は私以外にもいるかもしれません。現状では、GTDBから取得した系統樹そのままでは、iTOLで正常に開くことができません。その解決方法をまとめました。

用語説明

GTDBとは

GTDB(Genome Taxonomy Database)は、ゲノム系統発生に基づく標準的な微生物分類を確立するために作成されたデータベースです。このデータベースでは、バクテリアの120個の単一コピーマーカー遺伝子の連結セットを使用して推定(FastTreeを使用)されたゲノムツリーと、アーキアの53個(R07-RS207以降)のマーカー遺伝子の連結セットによるゲノムツリーが収録されています。加えて、これら微生物のゲノム配列も収録されています。

スクリーンショット 2024-07-19 021109.png

iTOLとは

iTOLは、系統樹の表示、注釈付け、管理を行うオンラインツールです。iTOLを使えば、系統樹の図をかっこよくつくることができます。
スクリーンショット 2024-07-19 022247.png

課題

「GTDBから取得した系統樹をiTOLで開くことができない」

正確には、ファイルを開くことはできますが、一部の枝しか表示されていません。GTDB-TKには、convert_to_itolというメソッドが用意されており、これを使えば問題は解決します。しかし、GTDB-Tkを使用するには、110Gほどのデータをダウンロードする必要があるなど、セットアップが面倒くさいです。そこで、convert_to_itolの部分を抜き出したサンプルプログラムを作成しました。
スクリーンショット 2024-07-19 023519.png

サンプルプログラム

添付したconvert_to_itol.pyをこのように実行すれば($ python convert_to_itol.py ./bac120.tree ./bac120_to_itol_noboot.tree)、iTOLで表示できるツリーファイルに変換できます。第一引数はGTDBから取得したファイルのパスで、第二引数は出力のファイルのパスです。このコードを実行するには、dendropyをインストールする必要があります。また、出力したファイルではブートストラップ値を除去しています。

convert_to_itol.py
import dendropy
import sys

def is_float(s):
    """Check if a string can be converted to a float.
    Parameters
    ----------
    s : str
        String to evaluate.
    Returns
    -------
    boolean
        True if string can be converted, else False.
    """
    try:
        float(s)
    except ValueError:
        return False

    return True

def parse_label(label):
    """Parse a Newick label which may contain a support value, taxon, and/or auxiliary information.
    Parameters
    ----------
    label : str
        Internal label in a Newick tree.
    Returns
    -------
    float
        Support value specified by label, or None
    str
        Taxon specified by label, or None
    str
        Auxiliary information, on None
    """

    support = None
    taxon = None
    auxiliary_info = None

    if label:
        label = label.strip()
        if '|' in label:
            label, auxiliary_info = label.split('|')

        if ':' in label:
            support, taxon = label.split(':')
            support = float(support)
        else:
            if is_float(label):
                support = float(label)
            elif label != '':
                taxon = label

    return support, taxon, auxiliary_info

def convert_to_itol(input_file, output_file):
    intree= dendropy.Tree.get_from_path(input_file,
                                        schema='newick',
                                        rooting='force-rooted',
                                        preserve_underscores=True)

    for node in intree.internal_nodes():
        if node.label:
            bootstrap,label,_aux = parse_label(node.label)
            if label:
                label = label.replace('; ',';').replace(';','|').replace("'","").lstrip('')
            node.label = label
            if node.edge.length:
                    #node.edge.length = f'{node.edge.length}[{bootstrap}]'
                    node.edge.length = f'{node.edge.length}'

    intree.write_to_path(output_file, schema='newick', suppress_rooting=True,unquoted_underscores=True)

if __name__ == '__main__':
    input_file = sys.argv[1]
    output_file = sys.argv[2]
    convert_to_itol(input_file, output_file)

結果

実際にiTOLで開いた様子がこちらです。
スクリーンショット 2024-07-20 035441.png

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0