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(上面的 write 调用应该采用的方式):

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

然后它随着消息而死:

无法在 treeFlipper.pl 第 7 行第 1 行的未定义值上调用方法“深度”。

我在这里找到了另一个我认为让我走上正轨的线程,但我还没有解决它:Perl 排序;干净地处理跨命名空间的 $a、$b 包全局变量

在第一个答案中切换到原型方法:

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

给我:

无法在 treeFlipper.pl 第 9 行第 1 行的 unblessed 引用上调用方法“深度”。

但是,如果我检查 ref 类型,那似乎是正确的:

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

原来这包括三个部分:

  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 回答