0

BioPerl に読み込んでいる系統樹があります。ツリーを出力するときにノードを垂直方向に並べ替えるために、カスタム ソート関数 (以下の「$depth_sort」) を使用したいと考えています。ただし、以下で使用される文書化された方法は、実際にソートせずに、読み込まれたのと同じ順序でツリーを書き出します。

use strict;
use Bio::TreeIO;

my $input = new Bio::TreeIO(-file=>"input.tree", -format=>'newick');
my $tree = $input->next_tree;

my $depth_sort = sub { $a->depth <=> $b->depth };

#this is the way it is supposed to work:
my $out = new Bio::TreeIO(
     -file     => ">sorted.tree", 
     -format   => 'newick', 
     -order_by => $depth_sort
);
$out->write_tree($tree);

代わりに、ツリーを手動で繰り返し処理して、何が起こっているかを確認できます。ローカルで独自の並べ替えを行うと、期待どおりに機能します。

my $rnode = $tree->get_root_node;
&printNode($rnode);

sub printNode {
    my $thisNode = shift;

    #print the node identity and depth, just to keep track:
    print "this is " . $thisNode->internal_id . 
          " with depth " . $thisNode->depth . "\n";

    if (! $thisNode->is_Leaf) {
        my @children = sort $depth_sort $thisNode->each_Descendent();
        for my $otherNode (@children) { &printNode($otherNode); }
    }
}

しかし、カスタムソートを each_Descendent に渡すと (上記の書き込み呼び出しが想定されている方法):

my @children = $thisNode->each_Descendent($depth_sort);

次に、次のメッセージで終了します。

treeFlipper.pl 行 7、行 1 で未定義の値に対してメソッド「depth」を呼び出すことはできません。

ここで、正しい軌道に乗っていると思われる別のスレッドを見つけましたが、まだ解決していません: Perl sorting; 名前空間全体で $a、$b パッケージ グローバルをきれいに処理する

最初の回答でプロトタイピング方法に切り替える:

my $depth_sort = sub ($$) { 
    my ($a1,$b1) = @_;
    return ($a1->depth <=> $b1->depth) };

私に与えます:

treeFlipper.pl 行 9、行 1 の unblessed 参照でメソッド「depth」を呼び出せません。

しかし、参照タイプを確認すると、それは正しいようです:

print ref($a1) . "\n";

与える

Bio::Tree::Node

参照を強制的に祝福しようとすると(これはおそらくひどいことです):

bless $a1, 'Bio::Tree::Node';
bless $b1, 'Bio::Tree::Node';

私は得る:

/usr/local/share/perl/5.14.2/Bio/Tree/Node.pm の 433 行目、1 行目の HASH リファレンスではありません。

そのスレッドの他のメソッド (呼び出し元を使用) では、同じ古い「未定義の値」エラーが発生します。

これは BioPerl の問題ですか、それとも (私が推測するように) まだ何か足りないのでしょうか? ありがとう!

編集:Ubuntu 12.04 LTSでPerl 5.14.2を使用

4

1 に答える 1

0

これには 3 つの部分があることが判明しました。

  1. 並べ替え関数は、プロトタイプを作成して直接インデックスを作成するか、呼び出し元のパッケージを介してアクセスする必要があります。これは、リンクした他のスレッドに記載されています。

  2. ソート機能を修正した後も機能しなかった理由は少し謎ですが、おそらく再現性はありません。BioPerlを再インストールすることで解決しました。

  3. 最後に、現在のバージョンの BioPerl (私は 1.6.9 を持っています) は「order_by」パラメーターを完全には実装していないことが判明しました -- Bio::TreeIO::newick コンストラクターは、渡された値を本来あるべきように設定しません。 . ただし、構築にパラメーターを明示的に設定することで、これを回避できました。

    my $out = new Bio::TreeIO(
         -file     => ">sorted.tree", 
         -format   => 'newick', 
    );
    $out->get_params->{'order_by'}=$depth_sort;
    $out->write_tree($tree);
    

これは期待どおりに機能しました。

于 2013-02-27T20:22:00.203 に答える